| // 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 whenWaitForAbsentResolves = Completer<void>(); | |
| driver | |
| .waitForAbsent(presentText) | |
| // ignore: unawaited_futures | |
| .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 whenWaitForResolves = Completer<void>(); | |
| driver | |
| .waitFor(presentText) | |
| // ignore: unawaited_futures | |
| .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); | |
| }); | |
| } |