// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:fake_async/fake_async.dart';
import 'package:flutter_driver/src/common/error.dart';
import 'package:flutter_driver/src/common/health.dart';
import 'package:flutter_driver/src/common/layer_tree.dart';
import 'package:flutter_driver/src/common/text_input_action.dart';
import 'package:flutter_driver/src/common/wait.dart';
import 'package:flutter_driver/src/driver/driver.dart';
import 'package:flutter_driver/src/driver/timeline.dart';
import 'package:vm_service/vm_service.dart' as vms;

import '../../common.dart';

/// Magical timeout value that's different from the default.
const Duration _kTestTimeout = Duration(milliseconds: 1234);
const String _kSerializedTestTimeout = '1234';
const String _kWebScriptPrefix = r"window.$flutterDriver('";
const String _kWebScriptSuffix = "')";

void main() {
  final List<String> log = <String>[];

  driverLog = (String source, String message) {
    log.add('$source: $message');
  };

  group('VMServiceFlutterDriver with logCommunicationToFile', () {
    late FakeVmService fakeClient;
    late FakeVM fakeVM;
    late vms.Isolate fakeIsolate;
    late VMServiceFlutterDriver driver;
    late File logFile;

    setUp(() {
      fakeIsolate = createFakeIsolate();
      fakeVM = FakeVM(fakeIsolate);
      fakeClient = FakeVmService(fakeVM);
      fakeClient.responses['waitFor'] = makeFakeResponse(<String, dynamic>{'status':'ok'});
    });

    tearDown(() {
      if (logFile.existsSync()) {
        logFile.deleteSync();
      }
    });

    group('logCommunicationToFile', () {
      test('logCommunicationToFile = true', () async {
        driver = VMServiceFlutterDriver.connectedTo(fakeClient, fakeIsolate);
        logFile = File(driver.logFilePathName);

        await driver.waitFor(find.byTooltip('foo'), timeout: _kTestTimeout);

        final bool exists = logFile.existsSync();
        expect(exists, true, reason: 'Not found ${logFile.path}');

        final String commandLog = await logFile.readAsString();
        const String waitForCommandLog = '>>> {command: waitFor, timeout: $_kSerializedTestTimeout, finderType: ByTooltipMessage, text: foo}';
        const String responseLog = '<<< {isError: false, response: {status: ok}}';

        expect(commandLog.contains(waitForCommandLog), true, reason: '$commandLog not contains $waitForCommandLog');
        expect(commandLog.contains(responseLog), true, reason: '$commandLog not contains $responseLog');
      });

      test('logCommunicationToFile = false', () async {
        driver = VMServiceFlutterDriver.connectedTo(fakeClient, fakeIsolate, logCommunicationToFile: false);
        logFile = File(driver.logFilePathName);
        // clear log file if left in filetree from previous run
        if (logFile.existsSync()) {
          logFile.deleteSync();
        }
        await driver.waitFor(find.byTooltip('foo'), timeout: _kTestTimeout);

        final bool exists = logFile.existsSync();
        expect(exists, false, reason: 'because ${logFile.path} exists');
      });

      test('logFilePathName was set when a new driver was created', () {
        driver = VMServiceFlutterDriver.connectedTo(fakeClient, fakeIsolate);
        logFile = File(driver.logFilePathName);
        expect(logFile.path, endsWith('.log'));
      });
    });
  });

  group('VMServiceFlutterDriver with printCommunication', () {
    late FakeVmService fakeClient;
    late FakeVM fakeVM;
    late vms.Isolate fakeIsolate;
    late VMServiceFlutterDriver driver;

    setUp(() async {
      log.clear();
      fakeIsolate = createFakeIsolate();
      fakeVM = FakeVM(fakeIsolate);
      fakeClient = FakeVmService(fakeVM);
      fakeClient.responses['waitFor'] = makeFakeResponse(<String, dynamic>{'status':'ok'});
    });

    test('printCommunication = true', () async {
      driver = VMServiceFlutterDriver.connectedTo(fakeClient, fakeIsolate, printCommunication: true);
      await driver.waitFor(find.byTooltip('foo'), timeout: _kTestTimeout);
      expect(log, <String>[
        'VMServiceFlutterDriver: >>> {command: waitFor, timeout: $_kSerializedTestTimeout, finderType: ByTooltipMessage, text: foo}',
        'VMServiceFlutterDriver: <<< {isError: false, response: {status: ok}}',
      ]);
    });

    test('printCommunication = false', () async {
      driver = VMServiceFlutterDriver.connectedTo(fakeClient, fakeIsolate);
      await driver.waitFor(find.byTooltip('foo'), timeout: _kTestTimeout);
      expect(log, <String>[]);
    });
  });

  group('VMServiceFlutterDriver.connect', () {
    late FakeVmService fakeClient;
    late FakeVM fakeVM;
    late vms.Isolate fakeIsolate;

    void expectLogContains(String message) {
      expect(log, anyElement(contains(message)));
    }

    setUp(() {
      log.clear();
      fakeIsolate = createFakeIsolate();
      fakeVM = FakeVM(fakeIsolate);
      fakeClient = FakeVmService(fakeVM);
      vmServiceConnectFunction = (String url, Map<String, dynamic>? headers) async {
        return fakeClient;
      };
      fakeClient.responses['get_health'] = makeFakeResponse(<String, dynamic>{'status': 'ok'});
    });

    tearDown(() async {
      restoreVmServiceConnectFunction();
    });

    test('Retries while Dart VM service is not available', () async {
      // This test case will test the real implementation of `_waitAndConnect`.
      restoreVmServiceConnectFunction();

      // The actual behavior is to retry indefinitely until the Dart VM service
      // becomes available. `.timeout` is used here to exit the infinite loop,
      // expecting that no other types of error are thrown during the process.
      expect(
        vmServiceConnectFunction('http://foo.bar', <String, dynamic>{})
            .timeout(const Duration(seconds: 1)),
        throwsA(isA<TimeoutException>()),
      );
    });

    test('throws after retries if no isolate', () async {
      fakeVM.numberOfTriesBeforeResolvingIsolate = 10000;
      FakeAsync().run((FakeAsync time) {
        FlutterDriver.connect(dartVmServiceUrl: '');
        time.elapse(kUnusuallyLongTimeout);
      });
      expect(log, <String>[
        'VMServiceFlutterDriver: Connecting to Flutter application at ',
        'VMServiceFlutterDriver: The root isolate is taking an unusually long time to start.',
      ]);
    });

    test('Retries connections if isolate is not available', () async {
      fakeIsolate.pauseEvent = vms.Event(kind: vms.EventKind.kPauseStart, timestamp: 0);
      fakeVM.numberOfTriesBeforeResolvingIsolate = 5;
      final FlutterDriver driver = await FlutterDriver.connect(dartVmServiceUrl: '');
      expect(driver, isNotNull);
      expect(
        fakeClient.connectionLog,
        <String>[
          'getIsolate',
          'setFlag pause_isolates_on_start false',
          'resume',
          'streamListen Isolate',
          'getIsolate',
          'onIsolateEvent',
          'streamCancel Isolate',
        ],
      );
    });

    test('Connects to isolate number', () async {
      fakeIsolate.pauseEvent = vms.Event(kind: vms.EventKind.kPauseStart, timestamp: 0);
      final FlutterDriver driver = await FlutterDriver.connect(dartVmServiceUrl: '', isolateNumber: int.parse(fakeIsolate.number!));
      expect(driver, isNotNull);
      expect(
        fakeClient.connectionLog,
        <String>[
          'getIsolate',
          'setFlag pause_isolates_on_start false',
          'resume',
          'streamListen Isolate',
          'getIsolate',
          'onIsolateEvent',
          'streamCancel Isolate',
        ],
      );
    });

    test('connects to isolate paused at start', () async {
      fakeIsolate.pauseEvent = vms.Event(kind: vms.EventKind.kPauseStart, timestamp: 0);

      final FlutterDriver driver = await FlutterDriver.connect(dartVmServiceUrl: '');
      expect(driver, isNotNull);
      expectLogContains('Isolate is paused at start');
      expect(
        fakeClient.connectionLog,
        <String>[
          'getIsolate',
          'setFlag pause_isolates_on_start false',
          'resume',
          'streamListen Isolate',
          'getIsolate',
          'onIsolateEvent',
          'streamCancel Isolate',
        ],
      );
    });

    test('ignores setFlag failure', () async {
      fakeIsolate.pauseEvent = vms.Event(kind: vms.EventKind.kPauseStart, timestamp: 0);
      fakeClient.failOnSetFlag = true;

      final FlutterDriver driver = await FlutterDriver.connect(dartVmServiceUrl: '');
      expectLogContains('Failed to set pause_isolates_on_start=false, proceeding. '
                        'Error: Exception: setFlag failed');
      expect(driver, isNotNull);
    });


    test('connects to isolate paused mid-flight', () async {
      fakeIsolate.pauseEvent = vms.Event(kind: vms.EventKind.kPauseBreakpoint, timestamp: 0);

      final FlutterDriver driver = await FlutterDriver.connect(dartVmServiceUrl: '');
      expect(driver, isNotNull);
      expectLogContains('Isolate is paused mid-flight');
    });

    // This test simulates a situation when we believe that the isolate is
    // currently paused, but something else (e.g. a debugger) resumes it before
    // we do. There's no need to fail as we should be able to drive the app
    // just fine.
    test('connects despite losing the race to resume isolate', () async {
      fakeIsolate.pauseEvent = vms.Event(kind: vms.EventKind.kPauseBreakpoint, timestamp: 0);
      fakeClient.failOnResumeWith101 = true;

      final FlutterDriver driver = await FlutterDriver.connect(dartVmServiceUrl: '');
      expect(driver, isNotNull);
      expectLogContains('Attempted to resume an already resumed isolate');
    });

    test('connects to unpaused isolate', () async {
      fakeIsolate.pauseEvent = vms.Event(kind: vms.EventKind.kResume, timestamp: 0);

      final FlutterDriver driver = await FlutterDriver.connect(dartVmServiceUrl: '');
      expect(driver, isNotNull);
      expectLogContains('Isolate is not paused. Assuming application is ready.');
    });

    test('connects to unpaused when onExtensionAdded does not contain the '
      'driver extension', () async {
      fakeIsolate.pauseEvent = vms.Event(kind: vms.EventKind.kResume, timestamp: 0);
      fakeIsolate.extensionRPCs!.add('ext.flutter.driver');

      final FlutterDriver driver = await FlutterDriver.connect(dartVmServiceUrl: '');
      expect(driver, isNotNull);
      expectLogContains('Isolate is not paused. Assuming application is ready.');
    });
  });

  group('VMServiceFlutterDriver', () {
    late FakeVmService fakeClient;
    late FakeVM fakeVM;
    late vms.Isolate fakeIsolate;
    late VMServiceFlutterDriver driver;

    setUp(() {
      fakeIsolate = createFakeIsolate();
      fakeVM = FakeVM(fakeIsolate);
      fakeClient = FakeVmService(fakeVM);
      driver = VMServiceFlutterDriver.connectedTo(fakeClient, fakeIsolate);
      fakeClient.responses['tap'] = makeFakeResponse(<String, dynamic>{});
    });

    test('checks the health of the driver extension', () async {
      fakeClient.responses['get_health'] = makeFakeResponse(<String, dynamic>{'status': 'ok'});
      final Health result = await driver.checkHealth();
      expect(result.status, HealthStatus.ok);
    });

    test('closes connection', () async {
      await driver.close();
      expect(fakeClient.connectionLog.last, 'dispose');
    });

    group('ByValueKey', () {
      test('restricts value types', () async {
        expect(() => find.byValueKey(null), throwsDriverError);
      });

      test('finds by ValueKey', () async {
        await driver.tap(find.byValueKey('foo'), timeout: _kTestTimeout);
        expect(fakeClient.commandLog, <String>[
          'ext.flutter.driver {command: tap, timeout: $_kSerializedTestTimeout, finderType: ByValueKey, keyValueString: foo, keyValueType: String}',
        ]);
      });
    });

    group('BySemanticsLabel', () {
      test('finds by Semantic label using String', () async {
        await driver.tap(find.bySemanticsLabel('foo'), timeout: _kTestTimeout);
        expect(fakeClient.commandLog, <String>[
          'ext.flutter.driver {command: tap, timeout: $_kSerializedTestTimeout, finderType: BySemanticsLabel, label: foo}',
        ]);
      });

      test('finds by Semantic label using RegExp', () async {
        await driver.tap(find.bySemanticsLabel(RegExp('^foo')), timeout: _kTestTimeout);
        expect(fakeClient.commandLog, <String>[
          'ext.flutter.driver {command: tap, timeout: $_kSerializedTestTimeout, finderType: BySemanticsLabel, label: ^foo, isRegExp: true}',
        ]);
      });
    });

    group('tap', () {
      test('sends the tap command', () async {
        await driver.tap(find.text('foo'), timeout: _kTestTimeout);
        expect(fakeClient.commandLog, <String>[
          'ext.flutter.driver {command: tap, timeout: $_kSerializedTestTimeout, finderType: ByText, text: foo}',
        ]);
      });
    });

    group('getText', () {
      test('sends the getText command', () async {
        fakeClient.responses['get_text'] = makeFakeResponse(<String, dynamic>{'text': 'hello'});
        final String result = await driver.getText(find.byValueKey(123), timeout: _kTestTimeout);
        expect(result, 'hello');
        expect(fakeClient.commandLog, <String>[
          'ext.flutter.driver {command: get_text, timeout: $_kSerializedTestTimeout, finderType: ByValueKey, keyValueString: 123, keyValueType: int}',
        ]);
      });
    });

    group('sendTextInputAction', () {
      test('sends the SendTextInputAction command with action done', () async {
        fakeClient.responses['send_text_input_action'] = makeFakeResponse(<String, dynamic>{});
        await driver.sendTextInputAction(TextInputAction.done, timeout: _kTestTimeout);
        expect(fakeClient.commandLog, <String>[
          'ext.flutter.driver {command: send_text_input_action, timeout: $_kSerializedTestTimeout, action: done}',
        ]);
      });
    });

    group('getLayerTree', () {
      test('sends the getLayerTree command', () async {
        fakeClient.responses['get_layer_tree'] = makeFakeResponse(<String, String>{
          'tree': 'hello',
        });
        final LayerTree result = await driver.getLayerTree(timeout: _kTestTimeout);
        final LayerTree referenceTree = LayerTree.fromJson(<String, String>{
            'tree': 'hello',
          });
        expect(result.tree, referenceTree.tree);
        expect(fakeClient.commandLog, <String>[
          'ext.flutter.driver {command: get_layer_tree, timeout: $_kSerializedTestTimeout}',
        ]);
      });
    });

    group('waitFor', () {
      test('sends the waitFor command', () async {
        fakeClient.responses['waitFor'] = makeFakeResponse(<String, dynamic>{});
        await driver.waitFor(find.byTooltip('foo'), timeout: _kTestTimeout);
        expect(fakeClient.commandLog, <String>[
          'ext.flutter.driver {command: waitFor, timeout: $_kSerializedTestTimeout, finderType: ByTooltipMessage, text: foo}',
        ]);
      });
    });

    group('getWidgetDiagnostics', () {
      test('sends the getWidgetDiagnostics command', () async {
        fakeClient.responses['get_diagnostics_tree'] = makeFakeResponse(<String, dynamic>{});
        await driver.getWidgetDiagnostics(find.byTooltip('foo'), timeout: _kTestTimeout);
        expect(fakeClient.commandLog, <String>[
          'ext.flutter.driver {command: get_diagnostics_tree, timeout: $_kSerializedTestTimeout, finderType: ByTooltipMessage, text: foo, subtreeDepth: 0, includeProperties: true, diagnosticsType: widget}',
        ]);
      });
    });

    group('getRenderObjectDiagnostics', () {
      test('sends the getRenderObjectDiagnostics command', () async {
        fakeClient.responses['get_diagnostics_tree'] = makeFakeResponse(<String, dynamic>{});
        await driver.getRenderObjectDiagnostics(find.byTooltip('foo'), timeout: _kTestTimeout);
        expect(fakeClient.commandLog, <String>[
          'ext.flutter.driver {command: get_diagnostics_tree, timeout: $_kSerializedTestTimeout, finderType: ByTooltipMessage, text: foo, subtreeDepth: 0, includeProperties: true, diagnosticsType: renderObject}',
        ]);
      });
    });

    group('waitForCondition', () {
      test('sends the wait for NoPendingFrameCondition command', () async {
        fakeClient.responses['waitForCondition'] = makeFakeResponse(<String, dynamic>{});
        await driver.waitForCondition(const NoPendingFrame(), timeout: _kTestTimeout);
        expect(fakeClient.commandLog, <String>[
          'ext.flutter.driver {command: waitForCondition, timeout: $_kSerializedTestTimeout, conditionName: NoPendingFrameCondition}',
        ]);
      });

      test('sends the wait for NoPendingPlatformMessages command', () async {
        fakeClient.responses['waitForCondition'] = makeFakeResponse(<String, dynamic>{});
        await driver.waitForCondition(const NoPendingPlatformMessages(), timeout: _kTestTimeout);
        expect(fakeClient.commandLog, <String>[
          'ext.flutter.driver {command: waitForCondition, timeout: $_kSerializedTestTimeout, conditionName: NoPendingPlatformMessagesCondition}',
        ]);
      });

      test('sends the waitForCondition of combined conditions command', () async {
        fakeClient.responses['waitForCondition'] = makeFakeResponse(<String, dynamic>{});
        const SerializableWaitCondition combinedCondition =
            CombinedCondition(<SerializableWaitCondition>[NoPendingFrame(), NoTransientCallbacks()]);
        await driver.waitForCondition(combinedCondition, timeout: _kTestTimeout);
         expect(fakeClient.commandLog, <String>[
          'ext.flutter.driver {command: waitForCondition, timeout: $_kSerializedTestTimeout, conditionName: CombinedCondition, conditions: [{"conditionName":"NoPendingFrameCondition"},{"conditionName":"NoTransientCallbacksCondition"}]}',
        ]);
      });
    });

    group('waitUntilNoTransientCallbacks', () {
      test('sends the waitUntilNoTransientCallbacks command', () async {
        fakeClient.responses['waitForCondition'] = makeFakeResponse(<String, dynamic>{});
        await driver.waitUntilNoTransientCallbacks(timeout: _kTestTimeout);
        expect(fakeClient.commandLog, <String>[
          'ext.flutter.driver {command: waitForCondition, timeout: $_kSerializedTestTimeout, conditionName: NoTransientCallbacksCondition}',
        ]);
      });
    });

    group('waitUntilFirstFrameRasterized', () {
      test('sends the waitUntilFirstFrameRasterized command', () async {
        fakeClient.responses['waitForCondition'] = makeFakeResponse(<String, dynamic>{});
        await driver.waitUntilFirstFrameRasterized();
        expect(fakeClient.commandLog, <String>[
          'ext.flutter.driver {command: waitForCondition, conditionName: FirstFrameRasterizedCondition}',
        ]);
      });
    });

    group('getOffset', () {
      setUp(() {
        fakeClient.responses['get_offset'] = makeFakeResponse(<String, double>{
          'dx': 11,
          'dy': 12,
        });
      });

      test('sends the getCenter command', () async {
        final DriverOffset result = await driver.getCenter(find.byValueKey(123), timeout: _kTestTimeout);
        expect(result, const DriverOffset(11, 12));
        expect(fakeClient.commandLog, <String>[
           'ext.flutter.driver {command: get_offset, timeout: 1234, finderType: ByValueKey, keyValueString: 123, keyValueType: int, offsetType: center}',
        ]);
      });

      test('sends the getTopLeft command', () async {
        final DriverOffset result = await driver.getTopLeft(find.byValueKey(123), timeout: _kTestTimeout);
        expect(result, const DriverOffset(11, 12));
        expect(fakeClient.commandLog, <String>[
           'ext.flutter.driver {command: get_offset, timeout: 1234, finderType: ByValueKey, keyValueString: 123, keyValueType: int, offsetType: topLeft}',
        ]);
      });

      test('sends the getTopRight command', () async {
        final DriverOffset result = await driver.getTopRight(find.byValueKey(123), timeout: _kTestTimeout);
        expect(result, const DriverOffset(11, 12));
        expect(fakeClient.commandLog, <String>[
           'ext.flutter.driver {command: get_offset, timeout: 1234, finderType: ByValueKey, keyValueString: 123, keyValueType: int, offsetType: topRight}',
        ]);
      });

      test('sends the getBottomLeft command', () async {
        final DriverOffset result = await driver.getBottomLeft(find.byValueKey(123), timeout: _kTestTimeout);
        expect(result, const DriverOffset(11, 12));
        expect(fakeClient.commandLog, <String>[
           'ext.flutter.driver {command: get_offset, timeout: 1234, finderType: ByValueKey, keyValueString: 123, keyValueType: int, offsetType: bottomLeft}',
        ]);
      });

      test('sends the getBottomRight command', () async {
        final DriverOffset result = await driver.getBottomRight(find.byValueKey(123), timeout: _kTestTimeout);
        expect(result, const DriverOffset(11, 12));
        expect(fakeClient.commandLog, <String>[
           'ext.flutter.driver {command: get_offset, timeout: 1234, finderType: ByValueKey, keyValueString: 123, keyValueType: int, offsetType: bottomRight}',
        ]);
      });
    });

    group('clearTimeline', () {
      test('clears timeline', () async {
        await driver.clearTimeline();
        expect(fakeClient.connectionLog, contains('clearVMTimeline'));
      });
    });

    group('traceAction', () {
      test('without clearing timeline', () async {
        final Timeline timeline = await driver.traceAction(() async {
          fakeClient.connectionLog.add('action');
        }, retainPriorEvents: true);

        expect(fakeClient.connectionLog, const <String>[
          'setVMTimelineFlags [all]',
          'action',
          'getFlagList',
          'setVMTimelineFlags []',
          'getVMTimeline null null',
        ]);
        expect(timeline.events!.single.name, 'test event');
      });

      test('with clearing timeline', () async {
        final Timeline timeline = await driver.traceAction(() async {
          fakeClient.connectionLog.add('action');
        });

        expect(fakeClient.connectionLog, const <String>[
          'clearVMTimeline',
          'getVMTimelineMicros',
          'setVMTimelineFlags [all]',
          'action',
          'getVMTimelineMicros',
          'getFlagList',
          'setVMTimelineFlags []',
          'getVMTimeline 1 999999',
        ]);
        expect(timeline.events!.single.name, 'test event');
      });

      test('with time interval', () async {
        fakeClient.incrementMicros = true;
        fakeClient.timelineResponses[1000001] = vms.Timeline.parse(<String, dynamic>{
          'traceEvents': <dynamic>[
            <String, dynamic>{
              'name': 'test event 2',
            },
          ],
          'timeOriginMicros': 1000000,
          'timeExtentMicros': 999999,
        });
        final Timeline timeline = await driver.traceAction(() async {
          fakeClient.connectionLog.add('action');
        });

        expect(fakeClient.connectionLog, const <String>[
          'clearVMTimeline',
          'getVMTimelineMicros',
          'setVMTimelineFlags [all]',
          'action',
          'getVMTimelineMicros',
          'getFlagList',
          'setVMTimelineFlags []',
          'getVMTimeline 1 999999',
          'getVMTimeline 1000001 999999',
        ]);
        expect(timeline.events!.map((TimelineEvent event) => event.name), <String>[
          'test event',
          'test event 2',
        ]);
      });
    });

    group('traceAction with timeline streams', () {
      test('specify non-default timeline streams', () async {
        bool actionCalled = false;

        final Timeline timeline = await driver.traceAction(() async {
          actionCalled = true;
        },
        streams: const <TimelineStream>[
          TimelineStream.dart,
          TimelineStream.gc,
          TimelineStream.compiler,
        ],
        retainPriorEvents: true);

        expect(actionCalled, isTrue);
        expect(fakeClient.connectionLog, <String>[
          'setVMTimelineFlags [Dart, GC, Compiler]',
          'getFlagList',
          'setVMTimelineFlags []',
          'getVMTimeline null null',
        ]);

        expect(timeline.events!.single.name, 'test event');
      });
    });

    group('sendCommand error conditions', () {
      test('local default timeout', () async {
        log.clear();
        fakeClient.artificialExtensionDelay = Completer<void>().future;
        FakeAsync().run((FakeAsync time) {
          driver.waitFor(find.byTooltip('foo'));
          expect(log, <String>[]);
          time.elapse(kUnusuallyLongTimeout);
        });
        expect(log, <String>['VMServiceFlutterDriver: waitFor message is taking a long time to complete...']);
      });

      test('local custom timeout', () async {
        log.clear();
        fakeClient.artificialExtensionDelay = Completer<void>().future;
        FakeAsync().run((FakeAsync time) {
          final Duration customTimeout = kUnusuallyLongTimeout - const Duration(seconds: 1);
          driver.waitFor(find.byTooltip('foo'), timeout: customTimeout);
          expect(log, <String>[]);
          time.elapse(customTimeout);
        });
        expect(log, <String>['VMServiceFlutterDriver: waitFor message is taking a long time to complete...']);
      });

      test('remote error', () async {
        fakeClient.responses['waitFor'] = makeFakeResponse(<String, dynamic>{
          'message': 'This is a failure',
        }, isError: true);
        await expectLater(
          () => driver.waitFor(find.byTooltip('foo')),
          throwsA(isA<DriverError>().having(
            (DriverError error) => error.message,
            'message',
            'Error in Flutter application: {message: This is a failure}',
          )),
        );
      });

      test('uncaught remote error', () async {
        fakeClient.artificialExtensionDelay = Future<void>.error(
          vms.RPCError('callServiceExtension', 9999, 'test error'),
        );

        expect(driver.waitFor(find.byTooltip('foo')), throwsDriverError);
      });
    });

    group('setSemantics', () {
      test('can be enabled', () async {
        fakeClient.responses['set_semantics'] = makeFakeResponse(<String, Object>{
          'changedState': true,
        });
        await driver.setSemantics(true, timeout: _kTestTimeout);
        expect(fakeClient.commandLog, <String>[
          'ext.flutter.driver {command: set_semantics, timeout: $_kSerializedTestTimeout, enabled: true}',
        ]);
      });

      test('can be disabled', () async {
        fakeClient.responses['set_semantics'] = makeFakeResponse(<String, Object>{
          'changedState': false,
        });
        await driver.setSemantics(false, timeout: _kTestTimeout);
        expect(fakeClient.commandLog, <String>[
          'ext.flutter.driver {command: set_semantics, timeout: $_kSerializedTestTimeout, enabled: false}',
        ]);
      });
    });

    test('VMServiceFlutterDriver does not support webDriver', () async {
      expect(() => driver.webDriver, throwsUnsupportedError);
    });

    group('runUnsynchronized', () {
      test('wrap waitFor with runUnsynchronized', () async {
        fakeClient.responses['waitFor'] = makeFakeResponse(<String, dynamic>{});
        fakeClient.responses['set_frame_sync'] = makeFakeResponse(<String, dynamic>{});

        await driver.runUnsynchronized(() async  {
          await driver.waitFor(find.byTooltip('foo'), timeout: _kTestTimeout);
        });

        expect(fakeClient.commandLog, <String>[
          'ext.flutter.driver {command: set_frame_sync, enabled: false}',
          'ext.flutter.driver {command: waitFor, timeout: $_kSerializedTestTimeout, finderType: ByTooltipMessage, text: foo}',
          'ext.flutter.driver {command: set_frame_sync, enabled: true}',
        ]);
      });
    });
  });

  group('VMServiceFlutterDriver with custom timeout', () {
    late FakeVmService fakeClient;
    late FakeVM fakeVM;
    late vms.Isolate fakeIsolate;
    late VMServiceFlutterDriver driver;

    setUp(() {
      fakeIsolate = createFakeIsolate();
      fakeVM = FakeVM(fakeIsolate);
      fakeClient = FakeVmService(fakeVM);
      driver = VMServiceFlutterDriver.connectedTo(fakeClient, fakeIsolate);
      fakeClient.responses['get_health'] = makeFakeResponse(<String, dynamic>{'status': 'ok'});
    });

    test('GetHealth has no default timeout', () async {
      await driver.checkHealth();
      expect(
        fakeClient.commandLog,
        <String>['ext.flutter.driver {command: get_health}'],
      );
    });

    test('does not interfere with explicit timeouts', () async {
      await driver.checkHealth(timeout: _kTestTimeout);
      expect(
        fakeClient.commandLog,
        <String>['ext.flutter.driver {command: get_health, timeout: $_kSerializedTestTimeout}'],
      );
    });
  });

  group('WebFlutterDriver with logCommunicationToFile', () {
    late FakeFlutterWebConnection fakeConnection;
    late WebFlutterDriver driver;
    late File logFile;

    setUp(() {
      fakeConnection = FakeFlutterWebConnection();
      fakeConnection.supportsTimelineAction = true;
      fakeConnection.responses['waitFor'] = jsonEncode(makeFakeResponse(<String, dynamic>{'status': 'ok'}));
    });

    tearDown(() {
      if (logFile.existsSync()) {
        logFile.deleteSync();
      }
    });

    test('logCommunicationToFile = true', () async {
      driver = WebFlutterDriver.connectedTo(fakeConnection);
      logFile = File(driver.logFilePathName);
      await driver.waitFor(find.byTooltip('logCommunicationToFile test'), timeout: _kTestTimeout);

      final bool exists = logFile.existsSync();
      expect(exists, true, reason: 'Not found ${logFile.path}');

      final String commandLog = await logFile.readAsString();
      const String waitForCommandLog = '>>> {command: waitFor, timeout: 1234, finderType: ByTooltipMessage, text: logCommunicationToFile test}';
      const String responseLog = '<<< {isError: false, response: {status: ok}, type: Response}';

      expect(commandLog, contains(waitForCommandLog), reason: '$commandLog not contains $waitForCommandLog');
      expect(commandLog, contains(responseLog), reason: '$commandLog not contains $responseLog');
    });

    test('logCommunicationToFile = false', () async {
      driver = WebFlutterDriver.connectedTo(fakeConnection, logCommunicationToFile: false);
      logFile = File(driver.logFilePathName);
      // clear log file if left in filetree from previous run
      if (logFile.existsSync()) {
        logFile.deleteSync();
      }
      await driver.waitFor(find.byTooltip('logCommunicationToFile test'), timeout: _kTestTimeout);
      final bool exists = logFile.existsSync();
      expect(exists, false, reason: 'because ${logFile.path} exists');
    });
  });

  group('WebFlutterDriver with printCommunication', () {
    late FakeFlutterWebConnection fakeConnection;
    late WebFlutterDriver driver;

    setUp(() {
      log.clear();
      fakeConnection = FakeFlutterWebConnection();
      fakeConnection.supportsTimelineAction = true;
      fakeConnection.responses['waitFor'] = jsonEncode(makeFakeResponse(<String, dynamic>{'status': 'ok'}));
    });

    test('printCommunication = true', () async {
      driver = WebFlutterDriver.connectedTo(fakeConnection, printCommunication: true);
      await driver.waitFor(find.byTooltip('printCommunication test'), timeout: _kTestTimeout);
      expect(log, <String>[
        'WebFlutterDriver: >>> {command: waitFor, timeout: 1234, finderType: ByTooltipMessage, text: printCommunication test}',
        'WebFlutterDriver: <<< {isError: false, response: {status: ok}, type: Response}',
      ]);
    });

    test('printCommunication = false', () async {
      driver = WebFlutterDriver.connectedTo(fakeConnection);
      await driver.waitFor(find.byTooltip('printCommunication test'), timeout: _kTestTimeout);
      expect(log, <String>[]);
    });
  });

  group('WebFlutterDriver', () {
    late FakeFlutterWebConnection fakeConnection;
    late WebFlutterDriver driver;

    setUp(() {
      fakeConnection = FakeFlutterWebConnection();
      fakeConnection.supportsTimelineAction = true;
      driver = WebFlutterDriver.connectedTo(fakeConnection);
    });

    test('closes connection', () async {
      await driver.close();
    });

    group('ByValueKey', () {
      test('restricts value types', () async {
        expect(() => find.byValueKey(null),
            throwsDriverError);
      });

      test('finds by ValueKey', () async {
        fakeConnection.responses['tap'] = jsonEncode(makeFakeResponse(<String, dynamic>{}));
        await driver.tap(find.byValueKey('foo'), timeout: _kTestTimeout);
        expect(fakeConnection.commandLog, <String>[
          r'''window.$flutterDriver('{"command":"tap","timeout":"1234","finderType":"ByValueKey","keyValueString":"foo","keyValueType":"String"}') 0:00:01.234000''',
        ]);
      });
    });

    group('BySemanticsLabel', () {
      test('finds by Semantic label using String', () async {
        fakeConnection.responses['tap'] = jsonEncode(makeFakeResponse(<String, dynamic>{}));
        await driver.tap(find.bySemanticsLabel('foo'), timeout: _kTestTimeout);
        expect(fakeConnection.commandLog, <String>[
          r'''window.$flutterDriver('{"command":"tap","timeout":"1234","finderType":"BySemanticsLabel","label":"foo"}') 0:00:01.234000''',
        ]);
      });

      test('finds by Semantic label using RegExp', () async {
        fakeConnection.responses['tap'] = jsonEncode(makeFakeResponse(<String, dynamic>{}));
        await driver.tap(find.bySemanticsLabel(RegExp('^foo')), timeout: _kTestTimeout);
        expect(fakeConnection.commandLog, <String>[
          r'''window.$flutterDriver('{"command":"tap","timeout":"1234","finderType":"BySemanticsLabel","label":"^foo","isRegExp":"true"}') 0:00:01.234000''',
        ]);
      });
    });

    group('tap', () {
      test('sends the tap command', () async {
        fakeConnection.responses['tap'] = jsonEncode(makeFakeResponse(<String, dynamic>{}));
        await driver.tap(find.text('foo'), timeout: _kTestTimeout);
        expect(fakeConnection.commandLog, <String>[
          r'''window.$flutterDriver('{"command":"tap","timeout":"1234","finderType":"ByText","text":"foo"}') 0:00:01.234000''',
        ]);
      });
    });

    group('getText', () {
      test('sends the getText command', () async {
        fakeConnection.responses['get_text'] = jsonEncode(makeFakeResponse(<String, dynamic>{'text': 'hello'}));
        final String result = await driver.getText(find.byValueKey(123), timeout: _kTestTimeout);
        expect(result, 'hello');
        expect(fakeConnection.commandLog, <String>[
          r'''window.$flutterDriver('{"command":"get_text","timeout":"1234","finderType":"ByValueKey","keyValueString":"123","keyValueType":"int"}') 0:00:01.234000''',
        ]);
      });
    });

    group('waitFor', () {
      test('sends the waitFor command', () async {
        fakeConnection.responses['waitFor'] = jsonEncode(makeFakeResponse(<String, dynamic>{'text': 'hello'}));
        await driver.waitFor(find.byTooltip('foo'), timeout: _kTestTimeout);
        expect(fakeConnection.commandLog, <String>[
          r'''window.$flutterDriver('{"command":"waitFor","timeout":"1234","finderType":"ByTooltipMessage","text":"foo"}') 0:00:01.234000''',
        ]);
      });
    });

    group('waitForCondition', () {
      setUp(() {
        fakeConnection.responses['waitForCondition'] = jsonEncode(makeFakeResponse(<String, dynamic>{'text': 'hello'}));
      });

      test('sends the wait for NoPendingFrameCondition command', () async {
        await driver.waitForCondition(const NoPendingFrame(), timeout: _kTestTimeout);
        expect(fakeConnection.commandLog, <String>[
          r'''window.$flutterDriver('{"command":"waitForCondition","timeout":"1234","conditionName":"NoPendingFrameCondition"}') 0:00:01.234000''',
        ]);
      });

      test('sends the wait for NoPendingPlatformMessages command', () async {
        await driver.waitForCondition(const NoPendingPlatformMessages(), timeout: _kTestTimeout);
        expect(fakeConnection.commandLog, <String>[
          r'''window.$flutterDriver('{"command":"waitForCondition","timeout":"1234","conditionName":"NoPendingPlatformMessagesCondition"}') 0:00:01.234000''',
        ]);
      });

      test('sends the waitForCondition of combined conditions command', () async {
        const SerializableWaitCondition combinedCondition = CombinedCondition(
          <SerializableWaitCondition>[NoPendingFrame(), NoTransientCallbacks()],
        );
        await driver.waitForCondition(combinedCondition, timeout: _kTestTimeout);
        expect(fakeConnection.commandLog, <String>[
          r'''window.$flutterDriver('{"command":"waitForCondition","timeout":"1234","conditionName":"CombinedCondition","conditions":"[{\"conditionName\":\"NoPendingFrameCondition\"},{\"conditionName\":\"NoTransientCallbacksCondition\"}]"}') 0:00:01.234000''',
        ]);
      });
    });

    group('waitUntilNoTransientCallbacks', () {
      test('sends the waitUntilNoTransientCallbacks command', () async {
        fakeConnection.responses['waitForCondition'] = jsonEncode(makeFakeResponse(<String, dynamic>{}));
        await driver.waitUntilNoTransientCallbacks(timeout: _kTestTimeout);
        expect(fakeConnection.commandLog, <String>[
          r'''window.$flutterDriver('{"command":"waitForCondition","timeout":"1234","conditionName":"NoTransientCallbacksCondition"}') 0:00:01.234000''',
        ]);
      });
    });

    group('getOffset', () {
      setUp(() {
        fakeConnection.responses['get_offset'] = jsonEncode(makeFakeResponse(<String, double>{
          'dx': 11,
          'dy': 12,
        }));
      });

      test('sends the getCenter command', () async {
        final DriverOffset result = await driver.getCenter(find.byValueKey(123), timeout: _kTestTimeout);
        expect(result, const DriverOffset(11, 12));
        expect(fakeConnection.commandLog, <String>[
          r'''window.$flutterDriver('{"command":"get_offset","timeout":"1234","finderType":"ByValueKey","keyValueString":"123","keyValueType":"int","offsetType":"center"}') 0:00:01.234000''',
        ]);
      });

      test('sends the getTopLeft command', () async {
        final DriverOffset result = await driver.getTopLeft(find.byValueKey(123), timeout: _kTestTimeout);
        expect(result, const DriverOffset(11, 12));
        expect(fakeConnection.commandLog, <String>[
          r'''window.$flutterDriver('{"command":"get_offset","timeout":"1234","finderType":"ByValueKey","keyValueString":"123","keyValueType":"int","offsetType":"topLeft"}') 0:00:01.234000''',
        ]);
      });

      test('sends the getTopRight command', () async {
        final DriverOffset result = await driver.getTopRight(find.byValueKey(123), timeout: _kTestTimeout);
        expect(result, const DriverOffset(11, 12));
        expect(fakeConnection.commandLog, <String>[
          r'''window.$flutterDriver('{"command":"get_offset","timeout":"1234","finderType":"ByValueKey","keyValueString":"123","keyValueType":"int","offsetType":"topRight"}') 0:00:01.234000''',
        ]);
      });

      test('sends the getBottomLeft command', () async {
        final DriverOffset result = await driver.getBottomLeft(find.byValueKey(123), timeout: _kTestTimeout);
        expect(result, const DriverOffset(11, 12));
        expect(fakeConnection.commandLog, <String>[
          r'''window.$flutterDriver('{"command":"get_offset","timeout":"1234","finderType":"ByValueKey","keyValueString":"123","keyValueType":"int","offsetType":"bottomLeft"}') 0:00:01.234000''',
        ]);
      });

      test('sends the getBottomRight command', () async {
        final DriverOffset result = await driver.getBottomRight(find.byValueKey(123), timeout: _kTestTimeout);
        expect(result, const DriverOffset(11, 12));
        expect(fakeConnection.commandLog, <String>[
          r'''window.$flutterDriver('{"command":"get_offset","timeout":"1234","finderType":"ByValueKey","keyValueString":"123","keyValueType":"int","offsetType":"bottomRight"}') 0:00:01.234000''',
        ]);
      });
    });

    test('checks the health of the driver extension', () async {
      fakeConnection.responses['get_health'] = jsonEncode(makeFakeResponse(<String, dynamic>{'status': 'ok'}));
      await driver.checkHealth();
      expect(fakeConnection.commandLog, <String>[
        r'''window.$flutterDriver('{"command":"get_health"}') null''',
      ]);
    });

    group('WebFlutterDriver Unimplemented/Unsupported error', () {
      test('forceGC', () async {
        expect(driver.forceGC(), throwsUnimplementedError);
      });

      test('getVmFlags', () async {
        expect(driver.getVmFlags(), throwsUnimplementedError);
      });

      test('waitUntilFirstFrameRasterized', () async {
        expect(driver.waitUntilFirstFrameRasterized(), throwsUnimplementedError);
      });

      test('appIsolate', () async {
        expect(() => driver.appIsolate.extensionRPCs, throwsUnsupportedError);
      });

      test('serviceClient', () async {
        expect(() => driver.serviceClient.getVM(), throwsUnsupportedError);
      });
    });

    group('runUnsynchronized', () {
      test('wrap waitFor with runUnsynchronized', () async {
        fakeConnection.responses['waitFor'] = jsonEncode(makeFakeResponse(<String, dynamic>{'text': 'hello'}));
        fakeConnection.responses['set_frame_sync'] = jsonEncode(makeFakeResponse(<String, dynamic>{}));

        await driver.runUnsynchronized(() async {
          await driver.waitFor(find.byTooltip('foo'), timeout: _kTestTimeout);
        });

        expect(fakeConnection.commandLog, <String>[
          r'''window.$flutterDriver('{"command":"set_frame_sync","enabled":"false"}') null''',
          r'''window.$flutterDriver('{"command":"waitFor","timeout":"1234","finderType":"ByTooltipMessage","text":"foo"}') 0:00:01.234000''',
          r'''window.$flutterDriver('{"command":"set_frame_sync","enabled":"true"}') null''',
        ]);
      });
    });
  });

  group('WebFlutterDriver with non-chrome browser', () {
    FakeFlutterWebConnection fakeConnection;
    late WebFlutterDriver driver;

    setUp(() {
      fakeConnection = FakeFlutterWebConnection();
      driver = WebFlutterDriver.connectedTo(fakeConnection);
    });

    test('tracing', () async {
      expect(driver.traceAction(() async { return Future<dynamic>.value(); }), throwsUnsupportedError);
      expect(driver.startTracing(), throwsUnsupportedError);
      expect(driver.stopTracingAndDownloadTimeline(), throwsUnsupportedError);
      expect(driver.clearTimeline(), throwsUnsupportedError);
    });
  });
}

// This function will verify the format of the script and return the actual
// script. The script will be in the following format:
//   window.flutterDriver('[actual script]')
String _checkAndEncode(dynamic script) {
  expect(script, isA<String>());
  final String scriptString = script as String;
  expect(scriptString.startsWith(_kWebScriptPrefix), isTrue);
  expect(scriptString.endsWith(_kWebScriptSuffix), isTrue);
  // Strip prefix and suffix
  return scriptString.substring(_kWebScriptPrefix.length, script.length - 2);
}

vms.Response? makeFakeResponse(
  Map<String, dynamic> response, {
  bool isError = false,
}) {
  return vms.Response.parse(<String, dynamic>{
    'isError': isError,
    'response': response,
  });
}

class FakeFlutterWebConnection extends Fake implements FlutterWebConnection {
  @override
  bool supportsTimelineAction = false;

  Map<String, dynamic> responses = <String, dynamic>{};
  List<String> commandLog = <String>[];
  @override
  Future<dynamic> sendCommand(String script, Duration? duration) async {
    commandLog.add('$script $duration');
    final Map<String, dynamic> decoded = jsonDecode(_checkAndEncode(script)) as Map<String, dynamic>;
    final dynamic response = responses[decoded['command']];
    assert(response != null, 'Missing ${decoded['command']} in responses.');
    return response;
  }

  @override
  Future<void> close() async {
    return;
  }
}

class FakeVmService extends Fake implements vms.VmService {
  FakeVmService(this.vm);

  FakeVM? vm;
  bool failOnSetFlag = false;
  bool failOnResumeWith101 = false;

  final List<String> connectionLog = <String>[];

  @override
  Future<vms.VM> getVM() async => vm!;

  @override
  Future<vms.Isolate> getIsolate(String isolateId) async {
    connectionLog.add('getIsolate');
    if (isolateId == vm!.isolate!.id) {
      return vm!.isolate!;
    }
    throw UnimplementedError('getIsolate called with unrecognized $isolateId');
  }

  @override
  Future<vms.Success> resume(String isolateId, {String? step, int? frameIndex}) async {
    assert(isolateId == vm!.isolate!.id);
    connectionLog.add('resume');
    if (failOnResumeWith101) {
      throw vms.RPCError('resume', 101, '');
    }
    return vms.Success();
  }

  @override
  Future<vms.Success> streamListen(String streamId) async {
    connectionLog.add('streamListen $streamId');
    return vms.Success();
  }

  @override
  Future<vms.Success> streamCancel(String streamId) async {
    connectionLog.add('streamCancel $streamId');
    return vms.Success();
  }

  @override
  Future<vms.Response> setFlag(String name, String value) async {
    connectionLog.add('setFlag $name $value');
    if (failOnSetFlag) {
      throw Exception('setFlag failed');
    }
    return vms.Success();
  }

  @override
  Stream<vms.Event> get onIsolateEvent async* {
    connectionLog.add('onIsolateEvent');
    yield vms.Event(
      kind: vms.EventKind.kServiceExtensionAdded,
      extensionRPC: 'ext.flutter.driver',
      timestamp: 0,
    );
  }

  List<String> commandLog = <String>[];
  Map<String, vms.Response?> responses = <String, vms.Response?>{};
  Future<void>? artificialExtensionDelay;

  @override
  Future<vms.Response> callServiceExtension(String method, {Map<dynamic, dynamic>? args, String? isolateId}) async {
    commandLog.add('$method $args');
    await artificialExtensionDelay;

    final vms.Response response = responses[args!['command']]!;
    assert(response != null, 'Failed to create a response for ${args['command']}');
    return response;
  }

  @override
  Future<vms.Success> clearVMTimeline() async {
    connectionLog.add('clearVMTimeline');
    return vms.Success();
  }

  @override
  Future<vms.FlagList> getFlagList() async {
    connectionLog.add('getFlagList');
    return vms.FlagList(flags: <vms.Flag>[]);
  }

  int vmTimelineMicros = -1000000;
  bool incrementMicros = false;

  @override
  Future<vms.Timestamp> getVMTimelineMicros() async {
    connectionLog.add('getVMTimelineMicros');
    if (incrementMicros || vmTimelineMicros < 0) {
      vmTimelineMicros = vmTimelineMicros + 1000001;
    }
    return vms.Timestamp(timestamp: vmTimelineMicros);
  }

  @override
  Future<vms.Success> setVMTimelineFlags(List<String> recordedStreams) async {
    connectionLog.add('setVMTimelineFlags $recordedStreams');
    return vms.Success();
  }

  final Map<int, vms.Timeline?> timelineResponses = <int, vms.Timeline?>{
    1: vms.Timeline.parse(<String, dynamic>{
      'traceEvents': <dynamic>[
        <String, dynamic>{
          'name': 'test event',
        },
      ],
      'timeOriginMicros': 0,
      'timeExtentMicros': 999999,
    }),
  };

  @override
  Future<vms.Timeline> getVMTimeline({int? timeOriginMicros, int? timeExtentMicros}) async {
    connectionLog.add('getVMTimeline $timeOriginMicros $timeExtentMicros');
    final vms.Timeline timeline = timelineResponses[timeOriginMicros ?? 1]!;
    assert(timeline != null, 'Missing entry in timelineResponses[$timeOriginMicros]');
    return timeline;
  }

  @override
  Future<void> dispose() async {
    connectionLog.add('dispose');
  }

  @override
  Future<void> get onDone async {}
}

class FakeVM extends Fake implements vms.VM {
  FakeVM(this.isolate);

  vms.Isolate? isolate;

  int numberOfTriesBeforeResolvingIsolate = 0;

  @override
  List<vms.IsolateRef> get isolates {
    numberOfTriesBeforeResolvingIsolate -= 1;
    return <vms.Isolate>[
      if (numberOfTriesBeforeResolvingIsolate <= 0)
        isolate!,
    ];
  }
}

vms.Isolate createFakeIsolate() => vms.Isolate(
  id: '123',
  number: '123',
  extensionRPCs: <String>[],
);
