diff --git a/packages/material_ui/lib/src/tooltip.dart b/packages/material_ui/lib/src/tooltip.dart index afbb80d7cb44..98dadd40e1c2 100644 --- a/packages/material_ui/lib/src/tooltip.dart +++ b/packages/material_ui/lib/src/tooltip.dart @@ -566,6 +566,14 @@ class TooltipState extends State with SingleTickerProviderStateMixin { ignorePointer: widget.ignorePointer ?? widget.message != null, child: effectiveChild, ); + } else { + // A TooltipVisibility ancestor has disabled the tooltip overlay and its + // triggers, but the message should still be reported to assistive + // technology, matching what RawTooltip does when the tooltip is enabled. + effectiveChild = Semantics( + tooltip: excludeFromSemantics ? null : _tooltipMessage, + child: effectiveChild, + ); } return effectiveChild; diff --git a/packages/material_ui/test/tooltip_visibility_test.dart b/packages/material_ui/test/tooltip_visibility_test.dart index b8c70b3cfe46..4d3a16a840ce 100644 --- a/packages/material_ui/test/tooltip_visibility_test.dart +++ b/packages/material_ui/test/tooltip_visibility_test.dart @@ -189,6 +189,56 @@ void main() { await tester.pump(); expect(find.text(tooltipText), findsOneWidget); }); + + testWidgets('Tooltip contributes semantics when in TooltipVisibility with visible = false', ( + WidgetTester tester, + ) async { + // Regression test for https://github.com/flutter/flutter/issues/189062. + final SemanticsHandle handle = tester.ensureSemantics(); + const childKey = Key('child'); + + await tester.pumpWidget( + const MaterialApp( + home: TooltipVisibility( + visible: false, + child: Tooltip( + message: tooltipText, + child: SizedBox(key: childKey, width: 100.0, height: 100.0), + ), + ), + ), + ); + + expect(tester.getSemantics(find.byKey(childKey)), containsSemantics(tooltip: tooltipText)); + handle.dispose(); + }); + + testWidgets( + 'Tooltip in TooltipVisibility with visible = false contributes no semantics when excluded', + (WidgetTester tester) async { + final SemanticsHandle handle = tester.ensureSemantics(); + const childKey = Key('child'); + + await tester.pumpWidget( + const MaterialApp( + home: TooltipVisibility( + visible: false, + child: Tooltip( + message: tooltipText, + excludeFromSemantics: true, + child: SizedBox(key: childKey, width: 100.0, height: 100.0), + ), + ), + ), + ); + + expect( + tester.getSemantics(find.byKey(childKey)), + isNot(containsSemantics(tooltip: tooltipText)), + ); + handle.dispose(); + }, + ); } Future setWidgetForTooltipMode(