Problem
Tests sometimes need to assert that a tap failed for a semantic reason, for example because the target widget is inside an IgnorePointer.
Today the public signal for that case is the human-readable TestFailure.message.
That makes tests couple themselves to Spot's diagnostic prose, so a wording improvement can break users even when the behavior is unchanged.
Current workaround
await expectLater(
() => act.tap(spot<SaveButton>()),
throwsA(
isA<TestFailure>().having(
(error) => error.message,
'message',
contains('is wrapped in IgnorePointer'),
),
),
);
This proves the behavior, but it treats the error message as API.
It also makes it hard to distinguish intentional behavior assertions from brittle text snapshots.
Possible API
await expectLater(
() => act.tap(spot<SaveButton>()),
throwsSpotTapFailure(reason: SpotTapFailureReason.ignorePointer),
);
An alternative would be a non-throwing tap API that returns structured failure details.
final result = await act.tryTap(spot<SaveButton>());
expect(result.reason, SpotTapFailureReason.ignorePointer);
The exact shape is flexible.
The important part is that tests can assert the machine-readable reason while Spot remains free to improve the human-readable diagnostic message.
Reason examples
ignorePointer
absorbedPointer
offstage
notHitTestable
partiallyHitTestable
Problem
Tests sometimes need to assert that a tap failed for a semantic reason, for example because the target widget is inside an
IgnorePointer.Today the public signal for that case is the human-readable
TestFailure.message.That makes tests couple themselves to Spot's diagnostic prose, so a wording improvement can break users even when the behavior is unchanged.
Current workaround
This proves the behavior, but it treats the error message as API.
It also makes it hard to distinguish intentional behavior assertions from brittle text snapshots.
Possible API
An alternative would be a non-throwing tap API that returns structured failure details.
The exact shape is flexible.
The important part is that tests can assert the machine-readable reason while Spot remains free to improve the human-readable diagnostic message.
Reason examples
ignorePointerabsorbedPointeroffstagenotHitTestablepartiallyHitTestable