bySemanticsLabel method Null safety

Finder bySemanticsLabel(
  1. Pattern label,
  2. {bool skipOffstage = true}
)

Finds Semantics widgets matching the given label, either by RegExp.hasMatch or string equality.

The framework may combine semantics labels in certain scenarios, such as when multiple Text widgets are in a MaterialButton widget. In such a case, it may be preferable to match by regular expression. Consumers of this API must not introduce unsuitable content into the semantics tree for the purposes of testing; in particular, you should prefer matching by regular expression rather than by string if the framework has combined your semantics, and not try to force the framework to break up the semantics nodes. Breaking up the nodes would have an undesirable effect on screen readers and other accessibility services.

Sample code

expect(find.bySemanticsLabel('Back'), findsOneWidget);

If the skipOffstage argument is true (the default), then this skips nodes that are Offstage or that are from inactive Routes.

Implementation

Finder bySemanticsLabel(Pattern label, { bool skipOffstage = true }) {
  if (WidgetsBinding.instance.pipelineOwner.semanticsOwner == null) {
    throw StateError('Semantics are not enabled. '
                     'Make sure to call tester.ensureSemantics() before using '
                     'this finder, and call dispose on its return value after.');
  }
  return byElementPredicate(
    (Element element) {
      // Multiple elements can have the same renderObject - we want the "owner"
      // of the renderObject, i.e. the RenderObjectElement.
      if (element is! RenderObjectElement) {
        return false;
      }
      final String? semanticsLabel = element.renderObject.debugSemantics?.label;
      if (semanticsLabel == null) {
        return false;
      }
      return label is RegExp
          ? label.hasMatch(semanticsLabel)
          : label == semanticsLabel;
    },
    skipOffstage: skipOffstage,
  );
}