execute method

  1. @override
Future<void> execute({
  1. required CancelToken cancelToken,
  2. required TestReport report,
  3. required TestController tester,
})
override

Executes the step. This will first look for the Testable, get the value of the appropriate semantic field from the Testable, then compare that value against the set value.

Implementation

@override
Future<void> execute({
  required CancelToken cancelToken,
  required TestReport report,
  required TestController tester,
}) async {
  if (kReleaseMode) {
    throw Exception('$id does not support running in Release Mode.');
  }

  final semanticsHandle =
      WidgetsBinding.instance.pipelineOwner.ensureSemantics();

  try {
    final testableId = tester.resolveVariable(this.testableId);
    final value = tester.resolveVariable(this.value)?.toString();
    assert(testableId?.isNotEmpty == true);

    final name = "$id('$field', '$testableId', '$value')";
    log(
      name,
      tester: tester,
    );
    final finder = await waitFor(
      testableId,
      cancelToken: cancelToken,
      tester: tester,
      timeout: timeout,
    );

    await sleep(
      tester.delays.postFoundWidget,
      cancelStream: cancelToken.stream,
      tester: tester,
    );

    if (cancelToken.cancelled == true) {
      throw Exception('[CANCELLED]: step was cancelled by the test');
    }

    var widgetFinder = finder.evaluate();
    String? actual;
    var match = false;
    if (widgetFinder.isNotEmpty == true) {
      widgetFinder = finder.evaluate();

      final element = widgetFinder.first;
      final renderObject = element.renderObject!;

      final node = _getSemantics(renderObject);
      final data = node.getSemanticsData();
      final flags = data.flags;

      switch (field) {
        case 'currentValueLength':
          actual = data.currentValueLength.toString();
          break;
        case 'decreasedValue':
          actual = data.decreasedValue;
          break;
        case 'elevation':
          actual = data.elevation.toString();
          break;
        case 'hasImplicitScrolling':
          actual = (flags & SemanticsFlag.hasImplicitScrolling.index != 0)
              .toString();
          break;
        case 'hint':
          actual = data.hint.toString();
          break;
        case 'increasedValue':
          actual = data.increasedValue.toString();
          break;
        case 'isButton':
          actual = (flags & SemanticsFlag.isButton.index != 0).toString();
          break;
        case 'isChecked':
          actual = (flags & SemanticsFlag.isChecked.index != 0).toString();
          break;
        case 'isEnabled':
          actual = (flags & SemanticsFlag.isEnabled.index != 0).toString();
          break;
        case 'isFocusable':
          (flags & SemanticsFlag.isFocusable.index != 0).toString();
          break;
        case 'isFocused':
          actual = (flags & SemanticsFlag.isFocused.index != 0).toString();
          break;
        case 'isHeader':
          actual = (flags & SemanticsFlag.isHeader.index != 0).toString();
          break;
        case 'isHidden':
          actual = (flags & SemanticsFlag.isHidden.index != 0).toString();
          break;
        case 'isImage':
          actual = (flags & SemanticsFlag.isImage.index != 0).toString();
          break;
        case 'isInMutuallyExclusiveGroup':
          actual =
              (flags & SemanticsFlag.isInMutuallyExclusiveGroup.index != 0)
                  .toString();
          break;
        case 'isKeyboardKey':
          actual =
              (flags & SemanticsFlag.isKeyboardKey.index != 0).toString();
          break;
        case 'isLink':
          actual = (flags & SemanticsFlag.isLink.index != 0).toString();
          break;
        case 'isMultiline':
          actual = (flags & SemanticsFlag.isMultiline.index != 0).toString();
          break;
        case 'isObscured':
          actual = (flags & SemanticsFlag.isObscured.index != 0).toString();
          break;
        case 'isReadOnly':
          actual = (flags & SemanticsFlag.isReadOnly.index != 0).toString();
          break;
        case 'isSelected':
          actual = (flags & SemanticsFlag.isSelected.index != 0).toString();
          break;
        case 'isSlider':
          actual = (flags & SemanticsFlag.isSlider.index != 0).toString();
          break;
        case 'isTextField':
          actual = (flags & SemanticsFlag.isTextField.index != 0).toString();
          break;
        case 'isToggled':
          actual = (flags & SemanticsFlag.isToggled.index != 0).toString();
          break;
        case 'label':
          actual = data.label.toString();
          break;
        case 'maxValueLength':
          actual = data.maxValueLength.toString();
          break;
        case 'scrollChildCount':
          actual = data.scrollChildCount.toString();
          break;
        case 'scrollExtentMax':
          actual = data.scrollExtentMax.toString();
          break;
        case 'scrollExtentMin':
          actual = data.scrollExtentMin.toString();
          break;
        case 'scrollIndex':
          actual = data.scrollIndex.toString();
          break;
        case 'scrollPosition':
          actual = data.scrollPosition.toString();
          break;
        case 'thickness':
          actual = data.thickness.toString();
          break;
        case 'value':
          actual = data.value.toString();
          break;

        default:
          throw Exception('Unknown field: [$field]');
      }

      match = actual == value;
    }
    if (match != true) {
      throw Exception(
        'testableId: [$testableId] -- actualValue: [$actual] != [$value].',
      );
    }
  } finally {
    semanticsHandle.dispose();
  }
}