// 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);
    }, timeout: Timeout.none);

    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'),
        )),
      );
    }, timeout: Timeout.none);

    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;
    }, timeout: Timeout.none);

    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'),
        )),
      );
    }, timeout: Timeout.none);

    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;
    }, timeout: Timeout.none);

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

    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);
    }, timeout: Timeout.none);

    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!'));
    }, timeout: Timeout.none);
  });
}
