// 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 'package:flutter_driver/flutter_driver.dart';

import 'package:test/test.dart' hide TypeMatcher, isInstanceOf;

void main() {
  group('FlutterDriver', () {
    final SerializableFinder presentText = find.text('present');
    late FlutterDriver driver;

    setUpAll(() async {
      driver = await FlutterDriver.connect();
    });

    tearDownAll(() async {
      await driver.close();
    });

    test('waitFor should find text "present"', () async {
      await driver.waitFor(presentText);
    });

    test('waitForAbsent should time out waiting for text "present" to disappear', () async {
      await expectLater(
        () => driver.waitForAbsent(presentText, timeout: const Duration(seconds: 1)),
        throwsA(isA<DriverError>().having(
          (DriverError error) => error.message,
          'message',
          contains('Timeout while executing waitForAbsent'),
        )),
      );
    });

    test('waitForAbsent should resolve when text "present" disappears', () async {
      // Begin waiting for it to disappear
      final Completer<void> whenWaitForAbsentResolves = Completer<void>();
      driver.waitForAbsent(presentText).then(
        whenWaitForAbsentResolves.complete,
        onError: whenWaitForAbsentResolves.completeError,
      );

      // Wait 1 second then make it disappear
      await Future<void>.delayed(const Duration(seconds: 1));
      await driver.tap(find.byValueKey('togglePresent'));

      // Ensure waitForAbsent resolves
      await whenWaitForAbsentResolves.future;
    });

    test('waitFor times out waiting for "present" to reappear', () async {
      await expectLater(
        () => driver.waitFor(presentText, timeout: const Duration(seconds: 1)),
        throwsA(isA<DriverError>().having(
          (DriverError error) => error.message,
          'message',
          contains('Timeout while executing waitFor'),
        )),
      );
    });

    test('waitFor should resolve when text "present" reappears', () async {
      // Begin waiting for it to reappear
      final Completer<void> whenWaitForResolves = Completer<void>();
      driver.waitFor(presentText).then(
        whenWaitForResolves.complete,
        onError: whenWaitForResolves.completeError,
      );

      // Wait 1 second then make it appear
      await Future<void>.delayed(const Duration(seconds: 1));
      await driver.tap(find.byValueKey('togglePresent'));

      // Ensure waitFor resolves
      await whenWaitForResolves.future;
    });

    test('waitForAbsent resolves immediately when the element does not exist', () async {
      await driver.waitForAbsent(find.text('that does not exist'));
    });

    test('uses hit test to determine tappable elements', () async {
      final SerializableFinder a = find.byValueKey('a');
      final SerializableFinder menu = find.byType('_DropdownMenu<Letter>');

      // Dropdown is closed
      await driver.waitForAbsent(menu);

      // Open dropdown
      await driver.tap(a);
      await driver.waitFor(menu);

      // Close it again
      await driver.tap(a);
      await driver.waitForAbsent(menu);
    });

    test('enters text in a text field', () async {
      final SerializableFinder textField = find.byValueKey('enter-text-field');
      await driver.tap(textField);
      await driver.enterText('Hello!');
      await driver.waitFor(find.text('Hello!'));
      await driver.enterText('World!');
      await driver.waitFor(find.text('World!'));
    });
  });
}
