execute method

Future<List<InteractionResult>> execute(
  1. List<PlannedInteraction> planned,
  2. String screenName
)

Implementation

Future<List<InteractionResult>> execute(
  List<PlannedInteraction> planned,
  String screenName,
) async {
  final results = <InteractionResult>[];
  final perfCapture = PerformanceCapture(
    vmService: vmService,
    isolateId: isolateId,
  );

  // Get screen dimensions for coordinate-based tapping
  final screenSize = await _getScreenSize();
  print('\nšŸŽ® Starting interaction testing on $screenName...');
  print('   ${planned.length} interactions planned\n');

  for (var i = 0; i < planned.length; i++) {
    final interaction = planned[i];
    final loc = interaction.file != null
        ? ' (${interaction.file}:${interaction.line})'
        : '';
    print('  [${i + 1}/${planned.length}] ${interaction.widgetType}$loc');

    if (interaction.type == InteractionType.skip) {
      print('    ${interaction.reason}');
      results.add(InteractionResult(
        interaction: interaction,
        executed: false,
        outcome: interaction.reason,
      ));
      continue;
    }

    try {
      // Capture widget position from VM service before interacting
      final position = await _getWidgetPosition(interaction);

      await perfCapture.startRecording();

      if (interaction.type == InteractionType.scroll) {
        await _performScroll(screenSize);
      } else if (interaction.type == InteractionType.typeText) {
        await _performType(interaction, position, screenSize);
      } else if (interaction.type == InteractionType.animate) {
        await Future.delayed(const Duration(milliseconds: 1500));
      } else {
        // TAP — use adb input tap with real coordinates
        await _performTap(position, screenSize);
      }

      await Future.delayed(const Duration(milliseconds: 600));

      final perf = await perfCapture.stopAndAnalyse(
        '${screenName}_${interaction.widgetType}',
      );

      final screenChanged = await _didScreenChange();
      final outcome = _describeOutcome(interaction, perf, screenChanged);
      print('    āœ… $outcome');

      if (perf.jankyFrames > 0) {
        print(
            '    āš ļø  ${perf.jankyFrames} janky frames (${perf.jankRate.toStringAsFixed(1)}%)');
      }

      results.add(InteractionResult(
        interaction: interaction,
        executed: true,
        outcome: outcome,
        performance: perf,
        screenChanged: screenChanged,
      ));

      // Go back if screen changed
      if (screenChanged) {
        await _goBack();
        await Future.delayed(const Duration(milliseconds: 800));
        print('    ā†©ļø  Went back');
      }
    } catch (e) {
      print('    āŒ Failed: $e');
      results.add(InteractionResult(
        interaction: interaction,
        executed: false,
        outcome: 'Failed: $e',
      ));
    }
  }

  return results;
}