diff --git a/packages/flutter/lib/src/semantics/semantics.dart b/packages/flutter/lib/src/semantics/semantics.dart index 4f6254f309..8d7223c6e2 100644 --- a/packages/flutter/lib/src/semantics/semantics.dart +++ b/packages/flutter/lib/src/semantics/semantics.dart @@ -2429,6 +2429,22 @@ class SemanticsNode with DiagnosticableTreeMixin { } } + /// When asserts are enabled, returns whether node is marked as dirty. + /// + /// Otherwise, returns null. + /// + /// This getter is intended for use in framework unit tests. Applications must + /// not depend on its value. + @visibleForTesting + bool? get debugIsDirty { + bool? isDirty; + assert(() { + isDirty = _dirty; + return true; + }()); + return isDirty; + } + bool _isDifferentFromCurrentSemanticAnnotation(SemanticsConfiguration config) { return _attributedLabel != config.attributedLabel || _attributedHint != config.attributedHint || @@ -2454,7 +2470,7 @@ class SemanticsNode with DiagnosticableTreeMixin { _areUserActionsBlocked != config.isBlockingUserActions || _headingLevel != config._headingLevel || _linkUrl != config._linkUrl || - _linkUrl != config._linkUrl; + _role != config.role; } // TAGS, LABELS, ACTIONS diff --git a/packages/flutter/test/semantics/semantics_test.dart b/packages/flutter/test/semantics/semantics_test.dart index b268c32674..418f02969c 100644 --- a/packages/flutter/test/semantics/semantics_test.dart +++ b/packages/flutter/test/semantics/semantics_test.dart @@ -464,6 +464,19 @@ void main() { expect(root.debugSemantics!.getSemanticsData().actions, expectedActions); }, ); + + test('updateWith marks node as dirty when role changes', () { + final SemanticsNode node = SemanticsNode(); + + expect(node.role, SemanticsRole.none); + expect(node.debugIsDirty, isFalse); + + final SemanticsConfiguration config = SemanticsConfiguration()..role = SemanticsRole.tab; + node.updateWith(config: config); + + expect(node.role, config.role); + expect(node.debugIsDirty, isTrue); + }); }); test('toStringDeep() does not throw with transform == null', () {