Why FlutterDriver doesn't add functionality to fetch Semantic Properties or Widget Properties using DiagnosticsTree data

57 views Asked by At

In our company, we have created after lots of struggle following dart module, which let us get value of any Widget or Widget's Semantics Properties:

widget_diagnostics_utils.dart

// ignore_for_file: avoid_print
class WidgetDiagnosticsUtils {
  WidgetDiagnosticsUtils(this.widgetDiagnostics);
  final Map<String, dynamic>? widgetDiagnostics;

  Map<String, dynamic>? findChildWidgetDiagnosticsWithRuntimeType(String type) {
    if (widgetDiagnostics == null) return null;

    // If self is of type: $type then return self.
    if (widgetDiagnostics?['widgetRuntimeType'] == type) {
      return widgetDiagnostics;
    }

    // If not childrens then return null.
    if (widgetDiagnostics?['children'] == null) return null;

    final nodeChilds = widgetDiagnostics?['children'] as List;
    for (final Map<String, dynamic> child in nodeChilds) {
      final widgetDiagnosticsUtils = WidgetDiagnosticsUtils(child);
      final result = widgetDiagnosticsUtils
          .findChildWidgetDiagnosticsWithRuntimeType(type);
      return result;
    }
    return null;
  }

  dynamic findWidgetDiagnosticsPropertyWithKey(
    Map<String, dynamic>? widgetDiagnostics,
    String key,
  ) {
    if (widgetDiagnostics == null) return null;
    if (widgetDiagnostics['properties'] == null) return null;

    // Cast 'properties' to List<Map<String, dynamic>>
    final properties = List<Map<String, dynamic>>.from(
      widgetDiagnostics['properties'] as dynamic,
    );

    for (final Map<String, dynamic> property in properties) {
      if (property['name'] == key) {
        return property['value'];
      }
    }
    return null;
  }
}

Example Use (Text):

final finder = find.byValueKey('your_parent_widget_key');

// find descendant child text
final descendantRadioWidget = find.descendant(of: ancestor, matching: find.byType('Text'));

final Map<String, dynamic>? widgetDiagnostics = await driver?.getWidgetDiagnostics(descendantRadioWidget, subtreeDepth: 1, timeout: const Duration(seconds: 30));

final utils = WidgetDiagnosticsUtils(widgetDiagnostics!);
final Map<String, dynamic>? childWidgetDiagnostics = utils.findChildWidgetDiagnosticsWithRuntimeType('Text');

const String property = 'value';
final dynamic value = utils.findWidgetDiagnosticsPropertyWithKey(childWidgetDiagnostics, property);

Example Use (Radio):

final finder = find.byValueKey('your_radio_widget_key');
final Map<String, dynamic>? widgetDiagnostics = await driver?.getWidgetDiagnostics(finder, subtreeDepth: 1, timeout: const Duration(seconds: 30));

final utils = WidgetDiagnosticsUtils(widgetDiagnostics!);
final Map<String, dynamic>? childWidgetDiagnostics = utils.findChildWidgetDiagnosticsWithRuntimeType('Semantics');

const String property = 'checked';
final dynamic value = utils.findWidgetDiagnosticsPropertyWithKey(childWidgetDiagnostics, property);

We have struggled a lot and it seems its very easy and FlutterDriver should add its support for everyone to use.

0

There are 0 answers