|  | // 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'); | 
|  | 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 { | 
|  | try { | 
|  | await driver.waitForAbsent(presentText, timeout: const Duration(seconds: 1)); | 
|  | fail('expected DriverError'); | 
|  | } on DriverError catch (error) { | 
|  | expect(error.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 { | 
|  | try { | 
|  | await driver.waitFor(presentText, timeout: const Duration(seconds: 1)); | 
|  | fail('expected DriverError'); | 
|  | } on DriverError catch (error) { | 
|  | expect(error.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!')); | 
|  | }); | 
|  | }); | 
|  | } |