From 3ece9c63d989182c8ae433f9b331c6e7544519f8 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 27 Jan 2021 23:55:26 -0800 Subject: [PATCH] Flutter_driver nnbd (#74856) --- dev/bots/test.dart | 2 +- .../flutter_driver/lib/flutter_driver.dart | 2 - .../flutter_driver/lib/src/common/error.dart | 4 +- .../lib/src/common/fuchsia_compat.dart | 10 +- .../flutter_driver/lib/src/driver/common.dart | 2 - .../flutter_driver/lib/src/driver/driver.dart | 84 +++++---- .../lib/src/driver/percentile_utils.dart | 2 - .../lib/src/driver/profiling_summarizer.dart | 18 +- .../driver/scene_display_lag_summarizer.dart | 6 +- .../lib/src/driver/timeline.dart | 51 +++--- .../lib/src/driver/timeline_summary.dart | 16 +- .../lib/src/driver/vmservice_driver.dart | 100 ++++++----- .../lib/src/driver/web_driver.dart | 18 +- packages/flutter_driver/pubspec.yaml | 13 +- packages/flutter_driver/test/common.dart | 2 - .../test/flutter_driver_test.dart | 119 ++++--------- .../test/src/real_tests/extension_test.dart | 166 +++++++++--------- .../test/src/real_tests/find_test.dart | 2 - .../src/real_tests/io_extension_test.dart | 4 +- .../src/real_tests/request_data_test.dart | 2 - .../src/real_tests/timeline_summary_test.dart | 8 +- .../test/src/real_tests/timeline_test.dart | 30 ++-- .../test/src/real_tests/wait_test.dart | 2 - .../flutter_driver/test_driver/failure.dart | 2 - .../test_driver/failure_test.dart | 2 - .../flutter_driver/test_driver/success.dart | 2 - .../test_driver/success_test.dart | 2 - 27 files changed, 291 insertions(+), 380 deletions(-) diff --git a/dev/bots/test.dart b/dev/bots/test.dart index b687ecce99..9c6cd2ef6e 100644 --- a/dev/bots/test.dart +++ b/dev/bots/test.dart @@ -669,7 +669,7 @@ Future _runFrameworkTests() async { await _runFlutterTest(path.join(flutterRoot, 'examples', 'hello_world'), options: soundNullSafetyOptions); await _runFlutterTest(path.join(flutterRoot, 'examples', 'layers'), options: soundNullSafetyOptions); await _runFlutterTest(path.join(flutterRoot, 'dev', 'benchmarks', 'test_apps', 'stocks')); - await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_driver'), tests: [path.join('test', 'src', 'real_tests')]); + await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_driver'), tests: [path.join('test', 'src', 'real_tests')], options: soundNullSafetyOptions); await _runFlutterTest(path.join(flutterRoot, 'packages', 'integration_test')); await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_goldens'), options: soundNullSafetyOptions); await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_localizations'), options: soundNullSafetyOptions); diff --git a/packages/flutter_driver/lib/flutter_driver.dart b/packages/flutter_driver/lib/flutter_driver.dart index c7eddfeebb..232bbecedd 100644 --- a/packages/flutter_driver/lib/flutter_driver.dart +++ b/packages/flutter_driver/lib/flutter_driver.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - /// Provides API to test Flutter applications that run on real /// devices and emulators. /// diff --git a/packages/flutter_driver/lib/src/common/error.dart b/packages/flutter_driver/lib/src/common/error.dart index 47b8bbdd42..8086778d00 100644 --- a/packages/flutter_driver/lib/src/common/error.dart +++ b/packages/flutter_driver/lib/src/common/error.dart @@ -14,10 +14,10 @@ class DriverError extends Error { final String message; /// The error object that was caught and wrapped by this error object, if any. - final dynamic originalError; + final Object? originalError; /// The stack trace that was caught and wrapped by this error object, if any. - final dynamic originalStackTrace; + final Object? originalStackTrace; @override String toString() { diff --git a/packages/flutter_driver/lib/src/common/fuchsia_compat.dart b/packages/flutter_driver/lib/src/common/fuchsia_compat.dart index a92cacd985..e60d2366a9 100644 --- a/packages/flutter_driver/lib/src/common/fuchsia_compat.dart +++ b/packages/flutter_driver/lib/src/common/fuchsia_compat.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - /// Convenience methods for Flutter application driving on Fuchsia. Can /// be run on either a host machine (making a remote connection to a Fuchsia /// device), or on the target Fuchsia machine. @@ -40,13 +38,13 @@ class _DummySshCommandRunner implements SshCommandRunner { } @override - String get sshConfigPath => null; + String get sshConfigPath => ''; @override String get address => InternetAddress.loopbackIPv4.address; @override - String get interface => null; + String get interface => ''; @override Future> run(String command) async { @@ -72,8 +70,8 @@ class _DummySshCommandRunner implements SshCommandRunner { Future _dummyPortForwardingFunction( String address, int remotePort, [ - String interface = '', - String configFile, + String? interface, + String? configFile, ]) async { return _DummyPortForwarder(remotePort, remotePort); } diff --git a/packages/flutter_driver/lib/src/driver/common.dart b/packages/flutter_driver/lib/src/driver/common.dart index 61b38c7942..7ad0f4b0f0 100644 --- a/packages/flutter_driver/lib/src/driver/common.dart +++ b/packages/flutter_driver/lib/src/driver/common.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import 'dart:io' show Platform; import 'package:file/file.dart'; diff --git a/packages/flutter_driver/lib/src/driver/driver.dart b/packages/flutter_driver/lib/src/driver/driver.dart index 6df6655b24..fd3af7950d 100644 --- a/packages/flutter_driver/lib/src/driver/driver.dart +++ b/packages/flutter_driver/lib/src/driver/driver.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import 'dart:io'; import 'package:meta/meta.dart'; @@ -95,14 +93,14 @@ abstract class FlutterDriver { /// for the VM. @visibleForTesting factory FlutterDriver.connectedTo({ - FlutterWebConnection webConnection, - vms.VmService serviceClient, - vms.Isolate appIsolate, + FlutterWebConnection? webConnection, + vms.VmService? serviceClient, + vms.Isolate? appIsolate, }) { if (webConnection != null) { return WebFlutterDriver.connectedTo(webConnection); } - return VMServiceFlutterDriver.connectedTo(serviceClient, appIsolate); + return VMServiceFlutterDriver.connectedTo(serviceClient!, appIsolate!); } /// Connects to a Flutter application. @@ -140,13 +138,13 @@ abstract class FlutterDriver { /// fail (completing with an error). A timeout can be applied by the caller /// using [Future.timeout] if necessary. static Future connect({ - String dartVmServiceUrl, + String? dartVmServiceUrl, bool printCommunication = false, bool logCommunicationToFile = true, - int isolateNumber, - Pattern fuchsiaModuleTarget, - Duration timeout, - Map headers, + int? isolateNumber, + Pattern? fuchsiaModuleTarget, + Duration? timeout, + Map? headers, }) async { if (Platform.environment['FLUTTER_WEB_TEST'] != null) { return WebFlutterDriver.connectWeb(hostUrl: dartVmServiceUrl, timeout: timeout); @@ -185,22 +183,22 @@ abstract class FlutterDriver { Future> sendCommand(Command command) async => throw UnimplementedError(); /// Checks the status of the Flutter Driver extension. - Future checkHealth({ Duration timeout }) async { + Future checkHealth({ Duration? timeout }) async { return Health.fromJson(await sendCommand(GetHealth(timeout: timeout))); } /// Returns a dump of the render tree. - Future getRenderTree({ Duration timeout }) async { + Future getRenderTree({ Duration? timeout }) async { return RenderTree.fromJson(await sendCommand(GetRenderTree(timeout: timeout))); } /// Returns a dump of the layer tree. - Future getLayerTree({ Duration timeout }) async { + Future getLayerTree({ Duration? timeout }) async { return LayerTree.fromJson(await sendCommand(GetLayerTree(timeout: timeout))); } /// Taps at the center of the widget located by [finder]. - Future tap(SerializableFinder finder, { Duration timeout }) async { + Future tap(SerializableFinder finder, { Duration? timeout }) async { await sendCommand(Tap(finder, timeout: timeout)); } @@ -213,17 +211,17 @@ abstract class FlutterDriver { /// /// * [FlutterDriver.runUnsynchronized], which will execute an action /// with frame sync disabled even while frames are pending. - Future waitFor(SerializableFinder finder, { Duration timeout }) async { + Future waitFor(SerializableFinder finder, { Duration? timeout }) async { await sendCommand(WaitFor(finder, timeout: timeout)); } /// Waits until [finder] can no longer locate the target. - Future waitForAbsent(SerializableFinder finder, { Duration timeout }) async { + Future waitForAbsent(SerializableFinder finder, { Duration? timeout }) async { await sendCommand(WaitForAbsent(finder, timeout: timeout)); } /// Waits until the given [waitCondition] is satisfied. - Future waitForCondition(SerializableWaitCondition waitCondition, {Duration timeout}) async { + Future waitForCondition(SerializableWaitCondition waitCondition, {Duration? timeout}) async { await sendCommand(WaitForCondition(waitCondition, timeout: timeout)); } @@ -231,7 +229,7 @@ abstract class FlutterDriver { /// /// Use this method when you need to wait for the moment when the application /// becomes "stable", for example, prior to taking a [screenshot]. - Future waitUntilNoTransientCallbacks({ Duration timeout }) async { + Future waitUntilNoTransientCallbacks({ Duration? timeout }) async { await sendCommand(WaitForCondition(const NoTransientCallbacks(), timeout: timeout)); } @@ -246,7 +244,7 @@ abstract class FlutterDriver { await sendCommand(const WaitForCondition(FirstFrameRasterized())); } - Future _getOffset(SerializableFinder finder, OffsetType type, { Duration timeout }) async { + Future _getOffset(SerializableFinder finder, OffsetType type, { Duration? timeout }) async { final GetOffset command = GetOffset(finder, type, timeout: timeout); final GetOffsetResult result = GetOffsetResult.fromJson(await sendCommand(command)); return DriverOffset(result.dx, result.dy); @@ -256,7 +254,7 @@ abstract class FlutterDriver { /// /// The offset is expressed in logical pixels and can be translated to /// device pixels via [dart:ui.FlutterView.devicePixelRatio]. - Future getTopLeft(SerializableFinder finder, { Duration timeout }) async { + Future getTopLeft(SerializableFinder finder, { Duration? timeout }) async { return _getOffset(finder, OffsetType.topLeft, timeout: timeout); } @@ -264,7 +262,7 @@ abstract class FlutterDriver { /// /// The offset is expressed in logical pixels and can be translated to /// device pixels via [dart:ui.FlutterView.devicePixelRatio]. - Future getTopRight(SerializableFinder finder, { Duration timeout }) async { + Future getTopRight(SerializableFinder finder, { Duration? timeout }) async { return _getOffset(finder, OffsetType.topRight, timeout: timeout); } @@ -272,7 +270,7 @@ abstract class FlutterDriver { /// /// The offset is expressed in logical pixels and can be translated to /// device pixels via [dart:ui.FlutterView.devicePixelRatio]. - Future getBottomLeft(SerializableFinder finder, { Duration timeout }) async { + Future getBottomLeft(SerializableFinder finder, { Duration? timeout }) async { return _getOffset(finder, OffsetType.bottomLeft, timeout: timeout); } @@ -280,7 +278,7 @@ abstract class FlutterDriver { /// /// The offset is expressed in logical pixels and can be translated to /// device pixels via [dart:ui.FlutterView.devicePixelRatio]. - Future getBottomRight(SerializableFinder finder, { Duration timeout }) async { + Future getBottomRight(SerializableFinder finder, { Duration? timeout }) async { return _getOffset(finder, OffsetType.bottomRight, timeout: timeout); } @@ -288,7 +286,7 @@ abstract class FlutterDriver { /// /// The offset is expressed in logical pixels and can be translated to /// device pixels via [dart:ui.FlutterView.devicePixelRatio]. - Future getCenter(SerializableFinder finder, { Duration timeout }) async { + Future getCenter(SerializableFinder finder, { Duration? timeout }) async { return _getOffset(finder, OffsetType.center, timeout: timeout); } @@ -317,7 +315,7 @@ abstract class FlutterDriver { SerializableFinder finder, { int subtreeDepth = 0, bool includeProperties = true, - Duration timeout, + Duration? timeout, }) async { return sendCommand(GetDiagnosticsTree( finder, @@ -325,7 +323,7 @@ abstract class FlutterDriver { subtreeDepth: subtreeDepth, includeProperties: includeProperties, timeout: timeout, - )); + )) as Map; } /// Returns a JSON map of the [DiagnosticsNode] that is associated with the @@ -350,7 +348,7 @@ abstract class FlutterDriver { SerializableFinder finder, { int subtreeDepth = 0, bool includeProperties = true, - Duration timeout, + Duration? timeout, }) async { return sendCommand(GetDiagnosticsTree( finder, @@ -358,7 +356,7 @@ abstract class FlutterDriver { subtreeDepth: subtreeDepth, includeProperties: includeProperties, timeout: timeout, - )); + )) as Map; } /// Tell the driver to perform a scrolling action. @@ -374,7 +372,7 @@ abstract class FlutterDriver { /// /// The move events are generated at a given [frequency] in Hz (or events per /// second). It defaults to 60Hz. - Future scroll(SerializableFinder finder, double dx, double dy, Duration duration, { int frequency = 60, Duration timeout }) async { + Future scroll(SerializableFinder finder, double dx, double dy, Duration duration, { int frequency = 60, Duration? timeout }) async { await sendCommand(Scroll(finder, dx, dy, duration, frequency, timeout: timeout)); } @@ -385,7 +383,7 @@ abstract class FlutterDriver { /// that lazily creates its children, like [ListView] or [CustomScrollView], /// then this method may fail because [finder] doesn't actually exist. /// The [scrollUntilVisible] method can be used in this case. - Future scrollIntoView(SerializableFinder finder, { double alignment = 0.0, Duration timeout }) async { + Future scrollIntoView(SerializableFinder finder, { double alignment = 0.0, Duration? timeout }) async { await sendCommand(ScrollIntoView(finder, alignment: alignment, timeout: timeout)); } @@ -417,7 +415,7 @@ abstract class FlutterDriver { double alignment = 0.0, double dxScroll = 0.0, double dyScroll = 0.0, - Duration timeout, + Duration? timeout, }) async { assert(scrollable != null); assert(item != null); @@ -442,7 +440,7 @@ abstract class FlutterDriver { } /// Returns the text in the `Text` widget located by [finder]. - Future getText(SerializableFinder finder, { Duration timeout }) async { + Future getText(SerializableFinder finder, { Duration? timeout }) async { return GetTextResult.fromJson(await sendCommand(GetText(finder, timeout: timeout))).text; } @@ -478,7 +476,7 @@ abstract class FlutterDriver { /// await driver.waitFor(find.text('World!')); // verify new text appears /// }); /// ``` - Future enterText(String text, { Duration timeout }) async { + Future enterText(String text, { Duration? timeout }) async { await sendCommand(EnterText(text, timeout: timeout)); } @@ -495,7 +493,7 @@ abstract class FlutterDriver { /// When enabled, the operating system's configured keyboard will not be /// invoked when the widget is focused, as the [SystemChannels.textInput] /// channel will be mocked out. - Future setTextEntryEmulation({ @required bool enabled, Duration timeout }) async { + Future setTextEntryEmulation({ required bool enabled, Duration? timeout }) async { assert(enabled != null); await sendCommand(SetTextEntryEmulation(enabled, timeout: timeout)); } @@ -506,7 +504,7 @@ abstract class FlutterDriver { /// It's expected that the application has registered a [DataHandler] /// callback in [enableFlutterDriverExtension] that can successfully handle /// these requests. - Future requestData(String message, { Duration timeout }) async { + Future requestData(String message, { Duration? timeout }) async { return RequestDataResult.fromJson(await sendCommand(RequestData(message, timeout: timeout))).message; } @@ -514,7 +512,7 @@ abstract class FlutterDriver { /// /// Returns true when the call actually changed the state from on to off or /// vice versa. - Future setSemantics(bool enabled, { Duration timeout }) async { + Future setSemantics(bool enabled, { Duration? timeout }) async { final SetSemanticsResult result = SetSemanticsResult.fromJson(await sendCommand(SetSemantics(enabled, timeout: timeout))); return result.changedState; } @@ -527,7 +525,7 @@ abstract class FlutterDriver { /// /// Semantics must be enabled to use this method, either using a platform /// specific shell command or [setSemantics]. - Future getSemanticsId(SerializableFinder finder, { Duration timeout }) async { + Future getSemanticsId(SerializableFinder finder, { Duration? timeout }) async { final Map jsonResponse = await sendCommand(GetSemanticsId(finder, timeout: timeout)); final GetSemanticsIdResult result = GetSemanticsIdResult.fromJson(jsonResponse); return result.id; @@ -693,7 +691,7 @@ abstract class FlutterDriver { /// With frame sync disabled, it's the responsibility of the test author to /// ensure that no action is performed while the app is undergoing a /// transition to avoid flakiness. - Future runUnsynchronized(Future action(), { Duration timeout }) async { + Future runUnsynchronized(Future action(), { Duration? timeout }) async { await sendCommand(SetFrameSync(false, timeout: timeout)); T result; try { @@ -750,8 +748,8 @@ class CommonFinders { /// If `firstMatchOnly` is true then only the first ancestor matching /// `matching` will be returned. Defaults to false. SerializableFinder ancestor({ - @required SerializableFinder of, - @required SerializableFinder matching, + required SerializableFinder of, + required SerializableFinder matching, bool matchRoot = false, bool firstMatchOnly = false, }) => Ancestor(of: of, matching: matching, matchRoot: matchRoot, firstMatchOnly: firstMatchOnly); @@ -765,8 +763,8 @@ class CommonFinders { /// If `firstMatchOnly` is true then only the first descendant matching /// `matching` will be returned. Defaults to false. SerializableFinder descendant({ - @required SerializableFinder of, - @required SerializableFinder matching, + required SerializableFinder of, + required SerializableFinder matching, bool matchRoot = false, bool firstMatchOnly = false, }) => Descendant(of: of, matching: matching, matchRoot: matchRoot, firstMatchOnly: firstMatchOnly); diff --git a/packages/flutter_driver/lib/src/driver/percentile_utils.dart b/packages/flutter_driver/lib/src/driver/percentile_utils.dart index 7b2b225b86..bec7bd7161 100644 --- a/packages/flutter_driver/lib/src/driver/percentile_utils.dart +++ b/packages/flutter_driver/lib/src/driver/percentile_utils.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - /// Returns the [p]-th percentile element from the [doubles]. /// `List` will be sorted. double findPercentile(List doubles, double p) { diff --git a/packages/flutter_driver/lib/src/driver/profiling_summarizer.dart b/packages/flutter_driver/lib/src/driver/profiling_summarizer.dart index a2fc53e427..0ed7dfd29d 100644 --- a/packages/flutter_driver/lib/src/driver/profiling_summarizer.dart +++ b/packages/flutter_driver/lib/src/driver/profiling_summarizer.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import 'percentile_utils.dart'; import 'timeline.dart'; @@ -63,7 +61,7 @@ class ProfilingSummarizer { assert(kProfilingEvents.contains(event.name)); final ProfileType type = _getProfileType(event.name); eventsByType[type] ??= []; - eventsByType[type].add(event); + eventsByType[type]!.add(event); } return ProfilingSummarizer._(eventsByType); } @@ -96,7 +94,7 @@ class ProfilingSummarizer { /// Returns true if there are events in the timeline corresponding to [profileType]. bool hasProfilingInfo(ProfileType profileType) { if (eventByType.containsKey(profileType)) { - return eventByType[profileType].isNotEmpty; + return eventByType[profileType]!.isNotEmpty; } else { return false; } @@ -104,7 +102,7 @@ class ProfilingSummarizer { /// Computes the average of the `profileType` over the recorded events. double computeAverage(ProfileType profileType) { - final List events = eventByType[profileType]; + final List events = eventByType[profileType]!; assert(events.isNotEmpty); final double total = events .map((TimelineEvent e) => _getProfileValue(profileType, e)) @@ -114,7 +112,7 @@ class ProfilingSummarizer { /// The [percentile]-th percentile `profileType` over the recorded events. double computePercentile(ProfileType profileType, double percentile) { - final List events = eventByType[profileType]; + final List events = eventByType[profileType]!; assert(events.isNotEmpty); final List doubles = events .map((TimelineEvent e) => _getProfileValue(profileType, e)) @@ -122,7 +120,7 @@ class ProfilingSummarizer { return findPercentile(doubles, percentile); } - static ProfileType _getProfileType(String eventName) { + static ProfileType _getProfileType(String? eventName) { switch (eventName) { case _kCpuProfile: return ProfileType.CPU; @@ -147,13 +145,11 @@ class ProfilingSummarizer { _getArgValue('owned_shared_memory_usage', e); return dirtyMem + ownedSharedMem; } - - throw Exception('Invalid $profileType.'); } double _getArgValue(String argKey, TimelineEvent e) { - assert(e.arguments.containsKey(argKey)); - final dynamic argVal = e.arguments[argKey]; + assert(e.arguments!.containsKey(argKey)); + final dynamic argVal = e.arguments![argKey]; assert(argVal is String); return double.parse(argVal as String); } diff --git a/packages/flutter_driver/lib/src/driver/scene_display_lag_summarizer.dart b/packages/flutter_driver/lib/src/driver/scene_display_lag_summarizer.dart index 50e72a5fc5..d6eaec031b 100644 --- a/packages/flutter_driver/lib/src/driver/scene_display_lag_summarizer.dart +++ b/packages/flutter_driver/lib/src/driver/scene_display_lag_summarizer.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import 'percentile_utils.dart'; import 'timeline.dart'; @@ -68,8 +66,8 @@ class SceneDisplayLagSummarizer { double _getVsyncTransitionsMissed(TimelineEvent e) { assert(e.name == kSceneDisplayLagEvent); - assert(e.arguments.containsKey(_kVsyncTransitionsMissed)); - final dynamic transitionsMissed = e.arguments[_kVsyncTransitionsMissed]; + assert(e.arguments!.containsKey(_kVsyncTransitionsMissed)); + final dynamic transitionsMissed = e.arguments![_kVsyncTransitionsMissed]; assert(transitionsMissed is String); return double.parse(transitionsMissed as String); } diff --git a/packages/flutter_driver/lib/src/driver/timeline.dart b/packages/flutter_driver/lib/src/driver/timeline.dart index 595879cda1..e7317560c9 100644 --- a/packages/flutter_driver/lib/src/driver/timeline.dart +++ b/packages/flutter_driver/lib/src/driver/timeline.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - /// Timeline data recorded by the Flutter runtime. class Timeline { /// Creates a timeline given JSON-encoded timeline data. @@ -25,27 +23,29 @@ class Timeline { /// /// This is parsed from "traceEvents" data within [json] and sorted by /// timestamp. Anything without a valid timestamp is put in the beginning. - final List events; + /// + /// This will be null if there are are no "traceEvents" in the [json]. + final List? events; } /// A single timeline event. class TimelineEvent { /// Creates a timeline event given JSON-encoded event data. TimelineEvent(this.json) - : name = json['name'] as String, - category = json['cat'] as String, - phase = json['ph'] as String, - processId = json['pid'] as int, - threadId = json['tid'] as int, + : name = json['name'] as String?, + category = json['cat'] as String?, + phase = json['ph'] as String?, + processId = json['pid'] as int?, + threadId = json['tid'] as int?, duration = json['dur'] != null ? Duration(microseconds: json['dur'] as int) : null, threadDuration = json['tdur'] != null ? Duration(microseconds: json['tdur'] as int) : null, - timestampMicros = json['ts'] as int, - threadTimestampMicros = json['tts'] as int, - arguments = json['args'] as Map; + timestampMicros = json['ts'] as int?, + threadTimestampMicros = json['tts'] as int?, + arguments = json['args'] as Map?; /// The original event JSON. final Map json; @@ -53,28 +53,28 @@ class TimelineEvent { /// The name of the event. /// /// Corresponds to the "name" field in the JSON event. - final String name; + final String? name; /// Event category. Events with different names may share the same category. /// /// Corresponds to the "cat" field in the JSON event. - final String category; + final String? category; /// For a given long lasting event, denotes the phase of the event, such as /// "B" for "event began", and "E" for "event ended". /// /// Corresponds to the "ph" field in the JSON event. - final String phase; + final String? phase; /// ID of process that emitted the event. /// /// Corresponds to the "pid" field in the JSON event. - final int processId; + final int? processId; /// ID of thread that issues the event. /// /// Corresponds to the "tid" field in the JSON event. - final int threadId; + final int? threadId; /// The duration of the event. /// @@ -82,7 +82,7 @@ class TimelineEvent { /// pair of begin/end events. /// /// Corresponds to the "dur" field in the JSON event. - final Duration duration; + final Duration? duration; /// The thread duration of the event. /// @@ -90,32 +90,31 @@ class TimelineEvent { /// pair of begin/end events. /// /// Corresponds to the "tdur" field in the JSON event. - final Duration threadDuration; + final Duration? threadDuration; /// Time passed since tracing was enabled, in microseconds. /// /// Corresponds to the "ts" field in the JSON event. - final int timestampMicros; + final int? timestampMicros; /// Thread clock time, in microseconds. /// /// Corresponds to the "tts" field in the JSON event. - final int threadTimestampMicros; + final int? threadTimestampMicros; /// Arbitrary data attached to the event. /// /// Corresponds to the "args" field in the JSON event. - final Map arguments; + final Map? arguments; } -List _parseEvents(Map json) { - final List jsonEvents = json['traceEvents'] as List; +List? _parseEvents(Map json) { + final List? jsonEvents = json['traceEvents'] as List?; if (jsonEvents == null) { return null; } - // TODO(vegorov): use instance method version of castFrom when it is available. final List timelineEvents = Iterable.castFrom>(jsonEvents) .map( @@ -123,8 +122,8 @@ List _parseEvents(Map json) { .toList(); timelineEvents.sort((TimelineEvent e1, TimelineEvent e2) { - final int ts1 = e1.timestampMicros; - final int ts2 = e2.timestampMicros; + final int? ts1 = e1.timestampMicros; + final int? ts2 = e2.timestampMicros; if (ts1 == null) { if (ts2 == null) { return 0; diff --git a/packages/flutter_driver/lib/src/driver/timeline_summary.dart b/packages/flutter_driver/lib/src/driver/timeline_summary.dart index 6146612588..b1f5d79617 100644 --- a/packages/flutter_driver/lib/src/driver/timeline_summary.dart +++ b/packages/flutter_driver/lib/src/driver/timeline_summary.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import 'dart:convert' show json, JsonEncoder; import 'dart:math' as math; @@ -197,7 +195,7 @@ class TimelineSummary { /// * [Timeline.fromJson], which explains detail about the timeline data. Future writeTimelineToFile( String traceName, { - String destinationDirectory, + String? destinationDirectory, bool pretty = false, }) async { destinationDirectory ??= testOutputsDirectory; @@ -209,7 +207,7 @@ class TimelineSummary { /// Writes [summaryJson] to a file. Future writeSummaryToFile( String traceName, { - String destinationDirectory, + String? destinationDirectory, bool pretty = false, }) async { destinationDirectory ??= testOutputsDirectory; @@ -225,13 +223,13 @@ class TimelineSummary { } List _extractNamedEvents(String name) { - return _timeline.events + return _timeline.events! .where((TimelineEvent event) => event.name == name) .toList(); } List _extractEventsWithNames(Set names) { - return _timeline.events + return _timeline.events! .where((TimelineEvent event) => names.contains(event.name)) .toList(); } @@ -244,7 +242,7 @@ class TimelineSummary { final List events = _extractNamedEvents(name); // Timeline does not guarantee that the first event is the "begin" event. - TimelineEvent begin; + TimelineEvent? begin; for (final TimelineEvent event in events) { if (event.phase == 'B') { begin = event; @@ -273,7 +271,7 @@ class TimelineSummary { return _extractDurations( name, (TimelineEvent beginEvent, TimelineEvent endEvent) { - return Duration(microseconds: endEvent.timestampMicros - beginEvent.timestampMicros); + return Duration(microseconds: endEvent.timestampMicros! - beginEvent.timestampMicros!); }, ); } @@ -282,7 +280,7 @@ class TimelineSummary { final List result = _extractDurations( name, (TimelineEvent beginEvent, TimelineEvent endEvent) { - return Duration(microseconds: beginEvent.timestampMicros); + return Duration(microseconds: beginEvent.timestampMicros!); }, ); diff --git a/packages/flutter_driver/lib/src/driver/vmservice_driver.dart b/packages/flutter_driver/lib/src/driver/vmservice_driver.dart index f1f26983b5..68c7bb95e6 100644 --- a/packages/flutter_driver/lib/src/driver/vmservice_driver.dart +++ b/packages/flutter_driver/lib/src/driver/vmservice_driver.dart @@ -2,15 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'package:file/file.dart' as f; import 'package:fuchsia_remote_debug_protocol/fuchsia_remote_debug_protocol.dart' as fuchsia; -import 'package:meta/meta.dart'; import 'package:path/path.dart' as p; import 'package:vm_service/vm_service.dart' as vms; import 'package:webdriver/async_io.dart' as async_io; @@ -41,12 +38,12 @@ class VMServiceFlutterDriver extends FlutterDriver { /// /// See [FlutterDriver.connect] for more documentation. static Future connect({ - String dartVmServiceUrl, + String? dartVmServiceUrl, bool printCommunication = false, bool logCommunicationToFile = true, - int isolateNumber, - Pattern fuchsiaModuleTarget, - Map headers, + int? isolateNumber, + Pattern? fuchsiaModuleTarget, + Map? headers, }) async { // If running on a Fuchsia device, connect to the first isolate whose name // matches FUCHSIA_MODULE_TARGET. @@ -93,32 +90,32 @@ class VMServiceFlutterDriver extends FlutterDriver { _log('Connecting to Flutter application at $dartVmServiceUrl'); final vms.VmService client = await vmServiceConnectFunction(dartVmServiceUrl, headers); - Future _waitForRootIsolate() async { + Future _waitForRootIsolate() async { bool _checkIsolate(vms.IsolateRef ref) => ref.number == isolateNumber.toString(); while (true) { final vms.VM vm = await client.getVM(); - if (vm.isolates.isEmpty || (isolateNumber != null && !vm.isolates.any(_checkIsolate))) { + if (vm.isolates!.isEmpty || (isolateNumber != null && !vm.isolates!.any(_checkIsolate))) { await Future.delayed(_kPauseBetweenReconnectAttempts); continue; } return isolateNumber == null - ? vm.isolates.first - : vm.isolates.firstWhere(_checkIsolate); + ? vm.isolates!.first + : vm.isolates!.firstWhere(_checkIsolate); } } - final vms.IsolateRef isolateRef = await _warnIfSlow( + final vms.IsolateRef isolateRef = (await _warnIfSlow( future: _waitForRootIsolate(), timeout: kUnusuallyLongTimeout, message: isolateNumber == null ? 'The root isolate is taking an unuusally long time to start.' : 'Isolate $isolateNumber is taking an unusually long time to start.', - ); + ))!; _log('Isolate found with number: ${isolateRef.number}'); - vms.Isolate isolate = await client.getIsolate(isolateRef.id); + vms.Isolate isolate = await client.getIsolate(isolateRef.id!); - if (isolate.pauseEvent.kind == vms.EventKind.kNone) { - isolate = await client.getIsolate(isolateRef.id); + if (isolate.pauseEvent!.kind == vms.EventKind.kNone) { + isolate = await client.getIsolate(isolateRef.id!); } final VMServiceFlutterDriver driver = VMServiceFlutterDriver.connectedTo( @@ -143,7 +140,7 @@ class VMServiceFlutterDriver extends FlutterDriver { _log('Failed to set pause_isolates_on_start=false, proceeding. Error: $e'); } - return client.resume(isolate.id).catchError((dynamic e) { + return client.resume(isolate.id!).catchError((Object e) { const int vmMustBePausedCode = 101; if (e is vms.RPCError && e.code == vmMustBePausedCode) { // No biggie; something else must have resumed the isolate @@ -167,9 +164,9 @@ class VMServiceFlutterDriver extends FlutterDriver { await client.streamListen(vms.EventStreams.kIsolate); final Future extensionAlreadyAdded = client - .getIsolate(isolateRef.id) + .getIsolate(isolateRef.id!) .then((vms.Isolate isolate) async { - if (isolate.extensionRPCs.contains(_flutterExtensionMethodName)) { + if (isolate.extensionRPCs!.contains(_flutterExtensionMethodName)) { return; } // Never complete. Rely on the stream listener to find the service @@ -178,7 +175,7 @@ class VMServiceFlutterDriver extends FlutterDriver { }); final Completer extensionAdded = Completer(); - StreamSubscription isolateAddedSubscription; + late StreamSubscription isolateAddedSubscription; isolateAddedSubscription = client.onIsolateEvent.listen( (vms.Event data) { @@ -200,19 +197,19 @@ class VMServiceFlutterDriver extends FlutterDriver { } // Attempt to resume isolate if it was paused - if (isolate.pauseEvent.kind == vms.EventKind.kPauseStart) { + if (isolate.pauseEvent!.kind == vms.EventKind.kPauseStart) { _log('Isolate is paused at start.'); await resumeLeniently(); - } else if (isolate.pauseEvent.kind == vms.EventKind.kPauseExit || - isolate.pauseEvent.kind == vms.EventKind.kPauseBreakpoint || - isolate.pauseEvent.kind == vms.EventKind.kPauseException || - isolate.pauseEvent.kind == vms.EventKind.kPauseInterrupted) { + } else if (isolate.pauseEvent!.kind == vms.EventKind.kPauseExit || + isolate.pauseEvent!.kind == vms.EventKind.kPauseBreakpoint || + isolate.pauseEvent!.kind == vms.EventKind.kPauseException || + isolate.pauseEvent!.kind == vms.EventKind.kPauseInterrupted) { // If the isolate is paused for any other reason, assume the extension is // already there. _log('Isolate is paused mid-flight.'); await resumeLeniently(); - } else if (isolate.pauseEvent.kind == vms.EventKind.kResume) { + } else if (isolate.pauseEvent!.kind == vms.EventKind.kResume) { _log('Isolate is not paused. Assuming application is ready.'); } else { _log( @@ -306,7 +303,7 @@ class VMServiceFlutterDriver extends FlutterDriver { @override Future> sendCommand(Command command) async { - Map response; + late Map response; try { final Map serialized = command.serialize(); _logCommunication('>>> $serialized'); @@ -314,12 +311,12 @@ class VMServiceFlutterDriver extends FlutterDriver { _flutterExtensionMethodName, isolateId: _appIsolate.id, args: serialized, - ).then>((vms.Response value) => value.json); - response = await _warnIfSlow>( + ).then>((vms.Response value) => value.json!); + response = (await _warnIfSlow>( future: future, timeout: command.timeout ?? kUnusuallyLongTimeout, message: '${command.kind} message is taking a long time to complete...', - ); + ))!; _logCommunication('<<< $response'); } catch (error, stackTrace) { throw DriverError( @@ -328,7 +325,7 @@ class VMServiceFlutterDriver extends FlutterDriver { stackTrace, ); } - if (response['isError'] as bool) + if ((response['isError'] as bool?) == true) throw DriverError('Error in Flutter application: ${response['response']}'); return response['response'] as Map; } @@ -348,14 +345,14 @@ class VMServiceFlutterDriver extends FlutterDriver { await Future.delayed(const Duration(seconds: 2)); final vms.Response result = await _serviceClient.callMethod('_flutter.screenshot'); - return base64.decode(result.json['screenshot'] as String); + return base64.decode(result.json!['screenshot'] as String); } @override Future>> getVmFlags() async { final vms.FlagList result = await _serviceClient.getFlagList(); - return result != null - ? result.flags.map((vms.Flag flag) => flag.toJson()).toList() + return result.flags != null + ? result.flags!.map((vms.Flag flag) => flag.toJson()).toList() : const >[]; } @@ -390,8 +387,8 @@ class VMServiceFlutterDriver extends FlutterDriver { @override Future stopTracingAndDownloadTimeline({ Duration timeout = kUnusuallyLongTimeout, - int startTime, - int endTime, + int? startTime, + int? endTime, }) async { assert(timeout != null); assert((startTime == null && endTime == null) || @@ -405,12 +402,12 @@ class VMServiceFlutterDriver extends FlutterDriver { ); if (startTime == null) { final vms.Timeline timeline = await _serviceClient.getVMTimeline(); - return Timeline.fromJson(timeline.json); + return Timeline.fromJson(timeline.json!); } const int kSecondInMicros = 1000000; int currentStart = startTime; int currentEnd = startTime + kSecondInMicros; // 1 second of timeline - final List> chunks = >[]; + final List?> chunks = ?>[]; do { final vms.Timeline chunk = await _serviceClient.getVMTimeline( timeOriginMicros: currentStart, @@ -421,11 +418,11 @@ class VMServiceFlutterDriver extends FlutterDriver { chunks.add(chunk.json); currentStart = currentEnd; currentEnd += kSecondInMicros; - } while (currentStart < endTime); + } while (currentStart < endTime!); return Timeline.fromJson({ 'traceEvents': [ - for (Map chunk in chunks) - ...chunk['traceEvents'] as List, + for (Map? chunk in chunks) + ...chunk!['traceEvents']! as List, ], }); } catch (error, stackTrace) { @@ -502,7 +499,7 @@ class VMServiceFlutterDriver extends FlutterDriver { } @override - Future runUnsynchronized(Future action(), { Duration timeout }) async { + Future runUnsynchronized(Future action(), { Duration? timeout }) async { await sendCommand(SetFrameSync(false, timeout: timeout)); T result; try { @@ -560,10 +557,10 @@ String _getWebSocketUrl(String url) { /// Waits for a real Dart VM service to become available, then connects using /// the [VMServiceClient]. -Future _waitAndConnect(String url, Map headers) async { +Future _waitAndConnect(String url, Map? headers) async { final String webSocketUrl = _getWebSocketUrl(url); int attempts = 0; - WebSocket socket; + late WebSocket socket; while (true) { try { socket = await WebSocket.connect(webSocketUrl, headers: headers); @@ -585,7 +582,7 @@ Future _waitAndConnect(String url, Map headers) await service.getVersion(); return service; } catch (e) { - await socket?.close(); + await socket.close(); if (attempts > 5) { _log('It is taking an unusually long time to connect to the VM...'); } @@ -623,10 +620,11 @@ List _timelineStreamsToString(List streams) { void _log(String message) { driverLog('VMServiceFlutterDriver', message); } -Future _warnIfSlow({ - @required Future future, - @required Duration timeout, - @required String message, + +Future _warnIfSlow({ + required Future future, + required Duration timeout, + required String message, }) { assert(future != null); assert(timeout != null); @@ -637,10 +635,10 @@ Future _warnIfSlow({ return null; }) // Don't duplicate errors if [future] completes with an error. - .catchError((dynamic e) => null); + .catchError((Object e, StackTrace s) => null); return future; } /// A function that connects to a Dart VM service given the `url` and `headers`. -typedef VMServiceConnectFunction = Future Function(String url, Map headers); +typedef VMServiceConnectFunction = Future Function(String url, Map? headers); diff --git a/packages/flutter_driver/lib/src/driver/web_driver.dart b/packages/flutter_driver/lib/src/driver/web_driver.dart index 7c5facd267..32c59361a5 100644 --- a/packages/flutter_driver/lib/src/driver/web_driver.dart +++ b/packages/flutter_driver/lib/src/driver/web_driver.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import 'dart:convert'; import 'dart:io'; @@ -53,7 +51,7 @@ class WebFlutterDriver extends FlutterDriver { /// DRIVER_SESSION_CAPABILITIES and ANDROID_CHROME_ON_EMULATOR for /// configurations. static Future connectWeb( - {String hostUrl, Duration timeout}) async { + {String? hostUrl, Duration? timeout}) async { hostUrl ??= Platform.environment['VM_SERVICE_URL']; final Map settings = { 'support-timeline-action': Platform.environment['SUPPORT_TIMELINE_ACTION'] == 'true', @@ -64,7 +62,7 @@ class WebFlutterDriver extends FlutterDriver { 'session-capabilities': Platform.environment['DRIVER_SESSION_CAPABILITIES'], }; final FlutterWebConnection connection = await FlutterWebConnection.connect - (hostUrl, settings, timeout: timeout); + (hostUrl!, settings, timeout: timeout); return WebFlutterDriver.connectedTo(connection); } @@ -90,7 +88,7 @@ class WebFlutterDriver extends FlutterDriver { final Map serialized = command.serialize(); try { final dynamic data = await _connection.sendCommand("window.\$flutterDriver('${jsonEncode(serialized)}')", command.timeout); - response = data != null ? json.decode(data as String) as Map : {}; + response = data != null ? (json.decode(data as String) as Map?)! : {}; } catch (error, stackTrace) { throw DriverError("Failed to respond to $command due to remote error\n : \$flutterDriver('${jsonEncode(serialized)}')", error, @@ -132,7 +130,7 @@ class WebFlutterDriver extends FlutterDriver { final List> events = >[]; for (final async_io.LogEntry entry in await _connection.logs.toList()) { if (_startTime.isBefore(entry.timestamp)) { - final Map data = jsonDecode(entry.message)['message'] as Map; + final Map data = jsonDecode(entry.message!)['message'] as Map; if (data['method'] == 'Tracing.dataCollected') { // 'ts' data collected from Chrome is in double format, conversion needed try { @@ -142,7 +140,7 @@ class WebFlutterDriver extends FlutterDriver { // data is corrupted, skip continue; } - events.add(data['params'] as Map); + events.add(data['params']! as Map); } } } @@ -203,7 +201,7 @@ class FlutterWebConnection { static Future connect( String url, Map settings, - {Duration timeout}) async { + {Duration? timeout}) async { final String sessionId = settings['session-id'].toString(); final Uri sessionUri = Uri.parse(settings['session-uri'].toString()); final async_io.WebDriver driver = async_io.WebDriver( @@ -226,7 +224,7 @@ class FlutterWebConnection { } /// Sends command via WebDriver to Flutter web application. - Future sendCommand(String script, Duration duration) async { + Future sendCommand(String script, Duration? duration) async { dynamic result; try { await _driver.execute(script, []); @@ -265,7 +263,7 @@ class FlutterWebConnection { } /// Waits until extension is installed. -Future waitUntilExtensionInstalled(async_io.WebDriver driver, Duration timeout) async { +Future waitUntilExtensionInstalled(async_io.WebDriver driver, Duration? timeout) async { await waitFor(() => driver.execute(r'return typeof(window.$flutterDriver)', []), matcher: 'function', diff --git a/packages/flutter_driver/pubspec.yaml b/packages/flutter_driver/pubspec.yaml index d1f209692f..2c143106c4 100644 --- a/packages/flutter_driver/pubspec.yaml +++ b/packages/flutter_driver/pubspec.yaml @@ -8,16 +8,16 @@ environment: dependencies: file: 6.0.0-nullsafety.4 - meta: 1.3.0-nullsafety.6 - path: 1.8.0-nullsafety.3 - vm_service: 6.0.1-nullsafety.0 - webdriver: 3.0.0-nullsafety.1 flutter: sdk: flutter flutter_test: sdk: flutter fuchsia_remote_debug_protocol: sdk: flutter + path: 1.8.0-nullsafety.3 + meta: 1.3.0-nullsafety.6 + vm_service: 6.0.1-nullsafety.0 + webdriver: 3.0.0-nullsafety.1 archive: 3.0.0-nullsafety.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" async: 2.5.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -27,7 +27,6 @@ dependencies: clock: 1.1.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" collection: 1.15.0-nullsafety.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" crypto: 3.0.0-nullsafety.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - fake_async: 1.2.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" matcher: 0.12.10-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" platform: 3.0.0-nullsafety.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" process: 4.0.0-nullsafety.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -42,7 +41,7 @@ dependencies: vector_math: 2.1.0-nullsafety.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: - quiver: 2.1.5 + fake_async: 1.2.0-nullsafety.3 test: 1.16.0-nullsafety.16 _fe_analyzer_shared: 14.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -77,4 +76,4 @@ dev_dependencies: webkit_inspection_protocol: 0.7.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 2.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" -# PUBSPEC CHECKSUM: 91b1 +# PUBSPEC CHECKSUM: 62c3 diff --git a/packages/flutter_driver/test/common.dart b/packages/flutter_driver/test/common.dart index 70b555d9df..5f55a15715 100644 --- a/packages/flutter_driver/test/common.dart +++ b/packages/flutter_driver/test/common.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import 'dart:io'; import 'package:flutter_driver/src/common/error.dart'; diff --git a/packages/flutter_driver/test/flutter_driver_test.dart b/packages/flutter_driver/test/flutter_driver_test.dart index eba8bb7fc3..787f556367 100644 --- a/packages/flutter_driver/test/flutter_driver_test.dart +++ b/packages/flutter_driver/test/flutter_driver_test.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import 'dart:async'; import 'dart:convert'; @@ -13,8 +11,8 @@ import 'package:flutter_driver/src/common/layer_tree.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:fake_async/fake_async.dart'; import 'package:vm_service/vm_service.dart' as vms; -import 'package:quiver/testing/async.dart'; import 'common.dart'; @@ -31,9 +29,9 @@ void main() { }; group('VMServiceFlutterDriver.connect', () { - FakeVmService fakeClient; - FakeVM fakeVM; - FakeIsolate fakeIsolate; + late FakeVmService fakeClient; + late FakeVM fakeVM; + late FakeIsolate fakeIsolate; void expectLogContains(String message) { expect(log, anyElement(contains(message))); @@ -44,7 +42,7 @@ void main() { fakeIsolate = FakeIsolate(); fakeVM = FakeVM(fakeIsolate); fakeClient = FakeVmService(fakeVM); - vmServiceConnectFunction = (String url, Map headers) async { + vmServiceConnectFunction = (String url, Map? headers) async { return fakeClient; }; fakeClient.responses['get_health'] = makeFakeResponse({'status': 'ok'}); @@ -176,10 +174,10 @@ void main() { }); group('VMServiceFlutterDriver', () { - FakeVmService fakeClient; + late FakeVmService fakeClient; FakeVM fakeVM; FakeIsolate fakeIsolate; - VMServiceFlutterDriver driver; + late VMServiceFlutterDriver driver; setUp(() { fakeIsolate = FakeIsolate(); @@ -230,10 +228,6 @@ void main() { }); group('tap', () { - test('requires a target reference', () async { - expect(driver.tap(null), throwsAssertionError); - }); - test('sends the tap command', () async { await driver.tap(find.text('foo'), timeout: _kTestTimeout); expect(fakeClient.commandLog, [ @@ -243,10 +237,6 @@ void main() { }); group('getText', () { - test('requires a target reference', () async { - expect(driver.getText(null), throwsAssertionError); - }); - test('sends the getText command', () async { fakeClient.responses['get_text'] = makeFakeResponse({'text': 'hello'}); final String result = await driver.getText(find.byValueKey(123), timeout: _kTestTimeout); @@ -274,10 +264,6 @@ void main() { }); group('waitFor', () { - test('requires a target reference', () async { - expect(driver.waitFor(null), throwsAssertionError); - }); - test('sends the waitFor command', () async { fakeClient.responses['waitFor'] = makeFakeResponse({}); await driver.waitFor(find.byTooltip('foo'), timeout: _kTestTimeout); @@ -363,14 +349,6 @@ void main() { }); }); - test('requires a target reference', () async { - expect(driver.getCenter(null), throwsAssertionError); - expect(driver.getTopLeft(null), throwsAssertionError); - expect(driver.getTopRight(null), throwsAssertionError); - expect(driver.getBottomLeft(null), throwsAssertionError); - expect(driver.getBottomRight(null), throwsAssertionError); - }); - test('sends the getCenter command', () async { final DriverOffset result = await driver.getCenter(find.byValueKey(123), timeout: _kTestTimeout); expect(result, const DriverOffset(11, 12)); @@ -432,7 +410,7 @@ void main() { 'setVMTimelineFlags []', 'getVMTimeline null null', ]); - expect(timeline.events.single.name, 'test event'); + expect(timeline.events!.single.name, 'test event'); }); test('with clearing timeline', () async { @@ -450,7 +428,7 @@ void main() { 'setVMTimelineFlags []', 'getVMTimeline 1 999999', ]); - expect(timeline.events.single.name, 'test event'); + expect(timeline.events!.single.name, 'test event'); }); test('with time interval', () async { @@ -479,7 +457,7 @@ void main() { 'getVMTimeline 1 999999', 'getVMTimeline 1000001 999999', ]); - expect(timeline.events.map((TimelineEvent event) => event.name), [ + expect(timeline.events!.map((TimelineEvent event) => event.name), [ 'test event', 'test event 2', ]); @@ -508,7 +486,7 @@ void main() { 'getVMTimeline null null' ]); - expect(timeline.events.single.name, 'test event'); + expect(timeline.events!.single.name, 'test event'); }); }); @@ -545,7 +523,7 @@ void main() { fail('expected an exception'); } catch (error) { expect(error, isA()); - expect(error.message, 'Error in Flutter application: {message: This is a failure}'); + expect((error as DriverError).message, 'Error in Flutter application: {message: This is a failure}'); } }); @@ -570,10 +548,10 @@ void main() { }); group('VMServiceFlutterDriver with custom timeout', () { - FakeVmService fakeClient; + late FakeVmService fakeClient; FakeVM fakeVM; FakeIsolate fakeIsolate; - VMServiceFlutterDriver driver; + late VMServiceFlutterDriver driver; setUp(() { fakeIsolate = FakeIsolate(); @@ -601,8 +579,8 @@ void main() { }); group('WebFlutterDriver', () { - FakeFlutterWebConnection fakeConnection; - WebFlutterDriver driver; + late FakeFlutterWebConnection fakeConnection; + late WebFlutterDriver driver; setUp(() { fakeConnection = FakeFlutterWebConnection(); @@ -648,10 +626,6 @@ void main() { }); group('tap', () { - test('requires a target reference', () async { - expect(driver.tap(null), throwsAssertionError); - }); - test('sends the tap command', () async { fakeConnection.responses['tap'] = jsonEncode(makeFakeResponse({})); await driver.tap(find.text('foo'), timeout: _kTestTimeout); @@ -662,10 +636,6 @@ void main() { }); group('getText', () { - test('requires a target reference', () async { - expect(driver.getText(null), throwsAssertionError); - }); - test('sends the getText command', () async { fakeConnection.responses['get_text'] = jsonEncode(makeFakeResponse({'text': 'hello'})); final String result = await driver.getText(find.byValueKey(123), timeout: _kTestTimeout); @@ -677,10 +647,6 @@ void main() { }); group('waitFor', () { - test('requires a target reference', () async { - expect(driver.waitFor(null), throwsAssertionError); - }); - test('sends the waitFor command', () async { fakeConnection.responses['waitFor'] = jsonEncode(makeFakeResponse({'text': 'hello'})); await driver.waitFor(find.byTooltip('foo'), timeout: _kTestTimeout); @@ -737,13 +703,6 @@ void main() { 'dy': 12, })); }); - test('requires a target reference', () async { - expect(driver.getCenter(null), throwsAssertionError); - expect(driver.getTopLeft(null), throwsAssertionError); - expect(driver.getTopRight(null), throwsAssertionError); - expect(driver.getBottomLeft(null), throwsAssertionError); - expect(driver.getBottomRight(null), throwsAssertionError); - }); test('sends the getCenter command', () async { final DriverOffset result = await driver.getCenter(find.byValueKey(123), timeout: _kTestTimeout); @@ -824,7 +783,7 @@ void main() { group('WebFlutterDriver with non-chrome browser', () { FakeFlutterWebConnection fakeConnection; - WebFlutterDriver driver; + late WebFlutterDriver driver; setUp(() { fakeConnection = FakeFlutterWebConnection(); @@ -848,15 +807,15 @@ void main() { /// and return the actual script. /// script will be in the following format: // window.flutterDriver('[actual script]') -String _checkAndEncode(dynamic script) { +String? _checkAndEncode(dynamic script) { expect(script, isA()); expect(script.startsWith(_kWebScriptPrefix), isTrue); expect(script.endsWith(_kWebScriptSuffix), isTrue); // Strip prefix and suffix - return script.substring(_kWebScriptPrefix.length, script.length - 2) as String; + return script.substring(_kWebScriptPrefix.length, script.length - 2) as String?; } -vms.Response makeFakeResponse( +vms.Response? makeFakeResponse( Map response, { bool isError = false, }) { @@ -873,9 +832,9 @@ class FakeFlutterWebConnection extends Fake implements FlutterWebConnection { Map responses = {}; List commandLog = []; @override - Future sendCommand(String script, Duration duration) async { + Future sendCommand(String script, Duration? duration) async { commandLog.add('$script $duration'); - final Map decoded = jsonDecode(_checkAndEncode(script)) as Map; + final Map decoded = jsonDecode(_checkAndEncode(script)!) as Map; final dynamic response = responses[decoded['command']]; assert(response != null, 'Missing ${decoded['command']} in responses.'); return response; @@ -890,27 +849,27 @@ class FakeFlutterWebConnection extends Fake implements FlutterWebConnection { class FakeVmService extends Fake implements vms.VmService { FakeVmService(this.vm); - FakeVM vm; + FakeVM? vm; bool failOnSetFlag = false; bool failOnResumeWith101 = false; final List connectionLog = []; @override - Future getVM() async => vm; + Future getVM() async => vm!; @override Future getIsolate(String isolateId) async { connectionLog.add('getIsolate'); - if (isolateId == vm.isolate.id) { - return vm.isolate; + if (isolateId == vm!.isolate!.id) { + return vm!.isolate!; } - return null; + throw UnimplementedError('getIsolate called with unrecognized $isolateId'); } @override - Future resume(String isolateId, {String step, int frameIndex}) async { - assert(isolateId == vm.isolate.id); + Future resume(String isolateId, {String? step, int? frameIndex}) async { + assert(isolateId == vm!.isolate!.id); connectionLog.add('resume'); if (failOnResumeWith101) { throw vms.RPCError('resume', 101, ''); @@ -950,15 +909,15 @@ class FakeVmService extends Fake implements vms.VmService { } List commandLog = []; - Map responses = {}; - Future artificialExtensionDelay; + Map responses = {}; + Future? artificialExtensionDelay; @override - Future callServiceExtension(String method, {Map args, String isolateId}) async { + Future callServiceExtension(String method, {Map? args, String? isolateId}) async { commandLog.add('$method $args'); await artificialExtensionDelay; - final vms.Response response = responses[args['command']]; + final vms.Response response = responses[args!['command']]!; assert(response != null, 'Failed to create a response for ${args['command']}'); return response; } @@ -993,7 +952,7 @@ class FakeVmService extends Fake implements vms.VmService { return vms.Success(); } - final Map timelineResponses = { + final Map timelineResponses = { 1: vms.Timeline.parse({ 'traceEvents': [ { @@ -1006,9 +965,9 @@ class FakeVmService extends Fake implements vms.VmService { }; @override - Future getVMTimeline({int timeOriginMicros, int timeExtentMicros}) async { + Future getVMTimeline({int? timeOriginMicros, int? timeExtentMicros}) async { connectionLog.add('getVMTimeline $timeOriginMicros $timeExtentMicros'); - final vms.Timeline timeline = timelineResponses[timeOriginMicros ?? 1]; + final vms.Timeline timeline = timelineResponses[timeOriginMicros ?? 1]!; assert(timeline != null, 'Missing entry in timelineResponses[$timeOriginMicros]'); return timeline; } @@ -1025,7 +984,7 @@ class FakeVmService extends Fake implements vms.VmService { class FakeVM extends Fake implements vms.VM { FakeVM(this.isolate); - vms.Isolate isolate; + vms.Isolate? isolate; int numberOfTriesBeforeResolvingIsolate = 0; @@ -1034,7 +993,7 @@ class FakeVM extends Fake implements vms.VM { numberOfTriesBeforeResolvingIsolate -= 1; return [ if (numberOfTriesBeforeResolvingIsolate <= 0) - isolate, + isolate!, ]; } } @@ -1047,7 +1006,7 @@ class FakeIsolate extends Fake implements vms.Isolate { String get id => number; @override - vms.Event pauseEvent; + vms.Event? pauseEvent; @override List get extensionRPCs => []; diff --git a/packages/flutter_driver/test/src/real_tests/extension_test.dart b/packages/flutter_driver/test/src/real_tests/extension_test.dart index b26b7b484a..9542ac71a0 100644 --- a/packages/flutter_driver/test/src/real_tests/extension_test.dart +++ b/packages/flutter_driver/test/src/real_tests/extension_test.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; @@ -37,14 +35,14 @@ Future silenceDriverLogger(AsyncCallback callback) async { void main() { group('waitUntilNoTransientCallbacks', () { - FlutterDriverExtension driverExtension; - Map result; + late FlutterDriverExtension driverExtension; + Map? result; int messageId = 0; - final List log = []; + final List log = []; setUp(() { result = null; - driverExtension = FlutterDriverExtension((String message) async { log.add(message); return (messageId += 1).toString(); }, false, true); + driverExtension = FlutterDriverExtension((String? message) async { log.add(message); return (messageId += 1).toString(); }, false, true); }); testWidgets('returns immediately when transient callback queue is empty', (WidgetTester tester) async { @@ -64,7 +62,7 @@ void main() { }); testWidgets('waits until no transient callbacks', (WidgetTester tester) async { - SchedulerBinding.instance.scheduleFrameCallback((_) { + SchedulerBinding.instance!.scheduleFrameCallback((_) { // Intentionally blank. We only care about existence of a callback. }); @@ -98,14 +96,14 @@ void main() { }); group('waitForCondition', () { - FlutterDriverExtension driverExtension; - Map result; + late FlutterDriverExtension driverExtension; + Map? result; int messageId = 0; - final List log = []; + final List log = []; setUp(() { result = null; - driverExtension = FlutterDriverExtension((String message) async { log.add(message); return (messageId += 1).toString(); }, false, true); + driverExtension = FlutterDriverExtension((String? message) async { log.add(message); return (messageId += 1).toString(); }, false, true); }); testWidgets('waiting for NoTransientCallbacks returns immediately when transient callback queue is empty', (WidgetTester tester) async { @@ -125,7 +123,7 @@ void main() { }); testWidgets('waiting for NoTransientCallbacks returns until no transient callbacks', (WidgetTester tester) async { - SchedulerBinding.instance.scheduleFrameCallback((_) { + SchedulerBinding.instance!.scheduleFrameCallback((_) { // Intentionally blank. We only care about existence of a callback. }); @@ -167,7 +165,7 @@ void main() { }); testWidgets('waiting for NoPendingFrame returns until no pending scheduled frame', (WidgetTester tester) async { - SchedulerBinding.instance.scheduleFrame(); + SchedulerBinding.instance!.scheduleFrame(); driverExtension.call(const WaitForCondition(NoPendingFrame()).serialize()) .then(expectAsync1((Map r) { @@ -210,8 +208,8 @@ void main() { testWidgets( 'waiting for combined conditions returns until no transient callbacks', (WidgetTester tester) async { - SchedulerBinding.instance.scheduleFrame(); - SchedulerBinding.instance.scheduleFrameCallback((_) { + SchedulerBinding.instance!.scheduleFrame(); + SchedulerBinding.instance!.scheduleFrameCallback((_) { // Intentionally blank. We only care about existence of a callback. }); @@ -239,8 +237,8 @@ void main() { testWidgets( 'waiting for combined conditions returns until no pending scheduled frame', (WidgetTester tester) async { - SchedulerBinding.instance.scheduleFrame(); - SchedulerBinding.instance.scheduleFrameCallback((_) { + SchedulerBinding.instance!.scheduleFrame(); + SchedulerBinding.instance!.scheduleFrameCallback((_) { // Intentionally blank. We only care about existence of a callback. }); @@ -288,11 +286,11 @@ void main() { 'waiting for NoPendingPlatformMessages returns until a single method channel call returns', (WidgetTester tester) async { const MethodChannel channel = MethodChannel('helloChannel', JSONMethodCodec()); const MessageCodec jsonMessage = JSONMessageCodec(); - ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler( - 'helloChannel', (ByteData message) { + ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler( + 'helloChannel', (ByteData? message) { return Future.delayed( const Duration(milliseconds: 10), - () => jsonMessage.encodeMessage(['hello world'])); + () => jsonMessage.encodeMessage(['hello world'])!); }); channel.invokeMethod('sayHello', 'hello'); @@ -322,20 +320,20 @@ void main() { const MessageCodec jsonMessage = JSONMessageCodec(); // Configures channel 1 const MethodChannel channel1 = MethodChannel('helloChannel1', JSONMethodCodec()); - ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler( - 'helloChannel1', (ByteData message) { + ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler( + 'helloChannel1', (ByteData? message) { return Future.delayed( const Duration(milliseconds: 10), - () => jsonMessage.encodeMessage(['hello world'])); + () => jsonMessage.encodeMessage(['hello world'])!); }); // Configures channel 2 const MethodChannel channel2 = MethodChannel('helloChannel2', JSONMethodCodec()); - ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler( - 'helloChannel2', (ByteData message) { + ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler( + 'helloChannel2', (ByteData? message) { return Future.delayed( const Duration(milliseconds: 20), - () => jsonMessage.encodeMessage(['hello world'])); + () => jsonMessage.encodeMessage(['hello world'])!); }); channel1.invokeMethod('sayHello', 'hello'); @@ -371,20 +369,20 @@ void main() { const MessageCodec jsonMessage = JSONMessageCodec(); // Configures channel 1 const MethodChannel channel1 = MethodChannel('helloChannel1', JSONMethodCodec()); - ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler( - 'helloChannel1', (ByteData message) { + ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler( + 'helloChannel1', (ByteData? message) { return Future.delayed( const Duration(milliseconds: 10), - () => jsonMessage.encodeMessage(['hello world'])); + () => jsonMessage.encodeMessage(['hello world'])!); }); // Configures channel 2 const MethodChannel channel2 = MethodChannel('helloChannel2', JSONMethodCodec()); - ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler( - 'helloChannel2', (ByteData message) { + ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler( + 'helloChannel2', (ByteData? message) { return Future.delayed( const Duration(milliseconds: 20), - () => jsonMessage.encodeMessage(['hello world'])); + () => jsonMessage.encodeMessage(['hello world'])!); }); channel1.invokeMethod('sayHello', 'hello'); @@ -422,20 +420,20 @@ void main() { const MessageCodec jsonMessage = JSONMessageCodec(); // Configures channel 1 const MethodChannel channel1 = MethodChannel('helloChannel1', JSONMethodCodec()); - ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler( - 'helloChannel1', (ByteData message) { + ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler( + 'helloChannel1', (ByteData? message) { return Future.delayed( const Duration(milliseconds: 20), - () => jsonMessage.encodeMessage(['hello world'])); + () => jsonMessage.encodeMessage(['hello world'])!); }); // Configures channel 2 const MethodChannel channel2 = MethodChannel('helloChannel2', JSONMethodCodec()); - ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler( - 'helloChannel2', (ByteData message) { + ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler( + 'helloChannel2', (ByteData? message) { return Future.delayed( const Duration(milliseconds: 10), - () => jsonMessage.encodeMessage(['hello world'])); + () => jsonMessage.encodeMessage(['hello world'])!); }); channel1.invokeMethod('sayHello', 'hello'); @@ -469,13 +467,13 @@ void main() { }); group('getSemanticsId', () { - FlutterDriverExtension driverExtension; + late FlutterDriverExtension driverExtension; setUp(() { - driverExtension = FlutterDriverExtension((String arg) async => '', true, true); + driverExtension = FlutterDriverExtension((String? arg) async => '', true, true); }); testWidgets('works when semantics are enabled', (WidgetTester tester) async { - final SemanticsHandle semantics = RendererBinding.instance.pipelineOwner.ensureSemantics(); + final SemanticsHandle semantics = RendererBinding.instance!.pipelineOwner.ensureSemantics(); await tester.pumpWidget( const Text('hello', textDirection: TextDirection.ltr)); @@ -499,7 +497,7 @@ void main() { }, semanticsEnabled: false); testWidgets('throws state error multiple matches are found', (WidgetTester tester) async { - final SemanticsHandle semantics = RendererBinding.instance.pipelineOwner.ensureSemantics(); + final SemanticsHandle semantics = RendererBinding.instance!.pipelineOwner.ensureSemantics(); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -520,7 +518,7 @@ void main() { }); testWidgets('getOffset', (WidgetTester tester) async { - final FlutterDriverExtension driverExtension = FlutterDriverExtension((String arg) async => '', true, true); + final FlutterDriverExtension driverExtension = FlutterDriverExtension((String? arg) async => '', true, true); Future getOffset(OffsetType offset) async { final Map arguments = GetOffset(ByValueKey(1), offset).serialize(); @@ -552,9 +550,9 @@ void main() { testWidgets('getText', (WidgetTester tester) async { await silenceDriverLogger(() async { - final FlutterDriverExtension driverExtension = FlutterDriverExtension((String arg) async => '', true, true); + final FlutterDriverExtension driverExtension = FlutterDriverExtension((String? arg) async => '', true, true); - Future getTextInternal(SerializableFinder search) async { + Future getTextInternal(SerializableFinder search) async { final Map arguments = GetText(search, timeout: const Duration(seconds: 1)).serialize(); final Map result = await driverExtension.call(arguments); if (result['isError'] as bool) { @@ -622,9 +620,9 @@ void main() { testWidgets('descendant finder', (WidgetTester tester) async { await silenceDriverLogger(() async { - final FlutterDriverExtension driverExtension = FlutterDriverExtension((String arg) async => '', true, true); + final FlutterDriverExtension driverExtension = FlutterDriverExtension((String? arg) async => '', true, true); - Future getDescendantText({ String of, bool matchRoot = false}) async { + Future getDescendantText({ String? of, bool matchRoot = false}) async { final Map arguments = GetText(Descendant( of: ByValueKey(of), matching: ByValueKey('text2'), @@ -655,7 +653,7 @@ void main() { expect(await getDescendantText(of: 'text2', matchRoot: true), 'Hello2'); // Find nothing - Future result = getDescendantText(of: 'text1', matchRoot: true); + Future result = getDescendantText(of: 'text1', matchRoot: true); await tester.pump(const Duration(seconds: 2)); expect(await result, null); @@ -667,9 +665,9 @@ void main() { testWidgets('descendant finder firstMatchOnly', (WidgetTester tester) async { await silenceDriverLogger(() async { - final FlutterDriverExtension driverExtension = FlutterDriverExtension((String arg) async => '', true, true); + final FlutterDriverExtension driverExtension = FlutterDriverExtension((String? arg) async => '', true, true); - Future getDescendantText() async { + Future getDescendantText() async { final Map arguments = GetText(Descendant( of: ByValueKey('column'), matching: const ByType('Text'), @@ -701,9 +699,9 @@ void main() { testWidgets('ancestor finder', (WidgetTester tester) async { await silenceDriverLogger(() async { - final FlutterDriverExtension driverExtension = FlutterDriverExtension((String arg) async => '', true, true); + final FlutterDriverExtension driverExtension = FlutterDriverExtension((String? arg) async => '', true, true); - Future getAncestorTopLeft({ String of, String matching, bool matchRoot = false}) async { + Future getAncestorTopLeft({ String? of, String? matching, bool matchRoot = false}) async { final Map arguments = GetOffset(Ancestor( of: ByValueKey(of), matching: ByValueKey(matching), @@ -759,7 +757,7 @@ void main() { ); // Find nothing - Future result = getAncestorTopLeft(of: 'leftchild', matching: 'leftchild'); + Future result = getAncestorTopLeft(of: 'leftchild', matching: 'leftchild'); await tester.pump(const Duration(seconds: 2)); expect(await result, null); @@ -771,9 +769,9 @@ void main() { testWidgets('ancestor finder firstMatchOnly', (WidgetTester tester) async { await silenceDriverLogger(() async { - final FlutterDriverExtension driverExtension = FlutterDriverExtension((String arg) async => '', true, true); + final FlutterDriverExtension driverExtension = FlutterDriverExtension((String? arg) async => '', true, true); - Future getAncestorTopLeft() async { + Future getAncestorTopLeft() async { final Map arguments = GetOffset(Ancestor( of: ByValueKey('leaf'), matching: const ByType('Container'), @@ -819,9 +817,9 @@ void main() { }); testWidgets('GetDiagnosticsTree', (WidgetTester tester) async { - final FlutterDriverExtension driverExtension = FlutterDriverExtension((String arg) async => '', true, true); + final FlutterDriverExtension driverExtension = FlutterDriverExtension((String? arg) async => '', true, true); - Future> getDiagnosticsTree(DiagnosticsType type, SerializableFinder finder, { int depth = 0, bool properties = true }) async { + Future> getDiagnosticsTree(DiagnosticsType type, SerializableFinder finder, { int depth = 0, bool properties = true }) async { final Map arguments = GetDiagnosticsTree(finder, type, subtreeDepth: depth, includeProperties: properties).serialize(); final Map response = await driverExtension.call(arguments); final DiagnosticsTreeResult result = DiagnosticsTreeResult(response['response'] as Map); @@ -838,12 +836,12 @@ void main() { ); // Widget - Map result = await getDiagnosticsTree(DiagnosticsType.widget, ByValueKey('Text'), depth: 0); + Map result = await getDiagnosticsTree(DiagnosticsType.widget, ByValueKey('Text'), depth: 0); expect(result['children'], isNull); // depth: 0 expect(result['widgetRuntimeType'], 'Text'); - List> properties = (result['properties'] as List).cast>(); - Map stringProperty = properties.singleWhere((Map property) => property['name'] == 'data'); + List> properties = (result['properties']! as List).cast>(); + Map stringProperty = properties.singleWhere((Map property) => property['name'] == 'data'); expect(stringProperty['description'], '"Hello World"'); expect(stringProperty['propertyType'], 'String'); @@ -852,11 +850,11 @@ void main() { expect(result['properties'], isNull); // properties: false result = await getDiagnosticsTree(DiagnosticsType.widget, ByValueKey('Text'), depth: 1); - List> children = (result['children'] as List).cast>(); + List> children = (result['children']! as List).cast>(); expect(children.single['children'], isNull); result = await getDiagnosticsTree(DiagnosticsType.widget, ByValueKey('Text'), depth: 100); - children = (result['children'] as List).cast>(); + children = (result['children']! as List).cast>(); expect(children.single['children'], isEmpty); // RenderObject @@ -870,22 +868,22 @@ void main() { expect(result['description'], startsWith('RenderParagraph')); result = await getDiagnosticsTree(DiagnosticsType.renderObject, ByValueKey('Text'), depth: 1); - children = (result['children'] as List).cast>(); - final Map textSpan = children.single; + children = (result['children']! as List).cast>(); + final Map textSpan = children.single; expect(textSpan['description'], 'TextSpan'); - properties = (textSpan['properties'] as List).cast>(); - stringProperty = properties.singleWhere((Map property) => property['name'] == 'text'); + properties = (textSpan['properties']! as List).cast>(); + stringProperty = properties.singleWhere((Map property) => property['name'] == 'text'); expect(stringProperty['description'], '"Hello World"'); expect(stringProperty['propertyType'], 'String'); expect(children.single['children'], isNull); result = await getDiagnosticsTree(DiagnosticsType.renderObject, ByValueKey('Text'), depth: 100); - children = (result['children'] as List).cast>(); + children = (result['children']! as List).cast>(); expect(children.single['children'], isEmpty); }); group('enableTextEntryEmulation', () { - FlutterDriverExtension driverExtension; + late FlutterDriverExtension driverExtension; Future> enterText() async { final Map arguments = const EnterText('foo').serialize(); @@ -905,7 +903,7 @@ void main() { ); testWidgets('enableTextEntryEmulation false', (WidgetTester tester) async { - driverExtension = FlutterDriverExtension((String arg) async => '', true, false); + driverExtension = FlutterDriverExtension((String? arg) async => '', true, false); await tester.pumpWidget(testWidget); @@ -914,7 +912,7 @@ void main() { }); testWidgets('enableTextEntryEmulation true', (WidgetTester tester) async { - driverExtension = FlutterDriverExtension((String arg) async => '', true, true); + driverExtension = FlutterDriverExtension((String? arg) async => '', true, true); await tester.pumpWidget(testWidget); @@ -944,7 +942,7 @@ void main() { testWidgets('unknown extension finder', (WidgetTester tester) async { final FlutterDriverExtension driverExtension = FlutterDriverExtension( - (String arg) async => '', + (String? arg) async => '', true, true, finders: [], @@ -960,12 +958,12 @@ void main() { final Map result = await getText(StubFinder('Text1')); expect(result['isError'], true); expect(result['response'] is String, true); - expect(result['response'] as String, contains('Unsupported search specification type Stub')); + expect(result['response'] as String?, contains('Unsupported search specification type Stub')); }); testWidgets('simple extension finder', (WidgetTester tester) async { final FlutterDriverExtension driverExtension = FlutterDriverExtension( - (String arg) async => '', + (String? arg) async => '', true, true, finders: [ @@ -987,7 +985,7 @@ void main() { testWidgets('complex extension finder', (WidgetTester tester) async { final FlutterDriverExtension driverExtension = FlutterDriverExtension( - (String arg) async => '', + (String? arg) async => '', true, true, finders: [ @@ -1009,7 +1007,7 @@ void main() { testWidgets('extension finder with command', (WidgetTester tester) async { final FlutterDriverExtension driverExtension = FlutterDriverExtension( - (String arg) async => '', + (String? arg) async => '', true, true, finders: [ @@ -1054,7 +1052,7 @@ void main() { testWidgets('unknown extension command', (WidgetTester tester) async { final FlutterDriverExtension driverExtension = FlutterDriverExtension( - (String arg) async => '', + (String? arg) async => '', true, true, commands: [], @@ -1070,12 +1068,12 @@ void main() { final Map result = await invokeCommand(ByValueKey('Button'), 10); expect(result['isError'], true); expect(result['response'] is String, true); - expect(result['response'] as String, contains('Unsupported command kind StubNestedCommand')); + expect(result['response'] as String?, contains('Unsupported command kind StubNestedCommand')); }); testWidgets('nested command', (WidgetTester tester) async { final FlutterDriverExtension driverExtension = FlutterDriverExtension( - (String arg) async => '', + (String? arg) async => '', true, true, commands: [ @@ -1101,7 +1099,7 @@ void main() { testWidgets('prober command', (WidgetTester tester) async { final FlutterDriverExtension driverExtension = FlutterDriverExtension( - (String arg) async => '', + (String? arg) async => '', true, true, commands: [ @@ -1127,11 +1125,11 @@ void main() { }); group('waitUntilFrameSync', () { - FlutterDriverExtension driverExtension; - Map result; + late FlutterDriverExtension driverExtension; + Map? result; setUp(() { - driverExtension = FlutterDriverExtension((String arg) async => '', true, true); + driverExtension = FlutterDriverExtension((String? arg) async => '', true, true); result = null; }); @@ -1154,7 +1152,7 @@ void main() { testWidgets( 'waits until no transient callbacks', (WidgetTester tester) async { - SchedulerBinding.instance.scheduleFrameCallback((_) { + SchedulerBinding.instance!.scheduleFrameCallback((_) { // Intentionally blank. We only care about existence of a callback. }); @@ -1180,7 +1178,7 @@ void main() { testWidgets( 'waits until no pending scheduled frame', (WidgetTester tester) async { - SchedulerBinding.instance.scheduleFrame(); + SchedulerBinding.instance!.scheduleFrame(); driverExtension.call(const WaitForCondition(NoPendingFrame()).serialize()) .then(expectAsync1((Map r) { diff --git a/packages/flutter_driver/test/src/real_tests/find_test.dart b/packages/flutter_driver/test/src/real_tests/find_test.dart index 9f1c83712b..1d06b7277d 100644 --- a/packages/flutter_driver/test/src/real_tests/find_test.dart +++ b/packages/flutter_driver/test/src/real_tests/find_test.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import 'package:flutter_driver/driver_extension.dart'; import 'package:flutter_driver/flutter_driver.dart'; import 'package:flutter_driver/src/common/find.dart'; diff --git a/packages/flutter_driver/test/src/real_tests/io_extension_test.dart b/packages/flutter_driver/test/src/real_tests/io_extension_test.dart index 5d5743b725..2e4c663e9b 100644 --- a/packages/flutter_driver/test/src/real_tests/io_extension_test.dart +++ b/packages/flutter_driver/test/src/real_tests/io_extension_test.dart @@ -2,15 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import 'package:flutter_driver/src/extension/_extension_io.dart'; import '../../common.dart'; void main() { group('test io_extension',() { - Future> Function(Map) call; + late Future> Function(Map) call; setUp(() { call = (Map args) async { diff --git a/packages/flutter_driver/test/src/real_tests/request_data_test.dart b/packages/flutter_driver/test/src/real_tests/request_data_test.dart index 7bb289b88e..d2da5703ee 100644 --- a/packages/flutter_driver/test/src/real_tests/request_data_test.dart +++ b/packages/flutter_driver/test/src/real_tests/request_data_test.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import 'package:flutter_driver/flutter_driver.dart'; import '../../common.dart'; diff --git a/packages/flutter_driver/test/src/real_tests/timeline_summary_test.dart b/packages/flutter_driver/test/src/real_tests/timeline_summary_test.dart index be02433513..bad01e3ca9 100644 --- a/packages/flutter_driver/test/src/real_tests/timeline_summary_test.dart +++ b/packages/flutter_driver/test/src/real_tests/timeline_summary_test.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import 'dart:convert' show json; import 'package:file/file.dart'; @@ -409,7 +407,7 @@ void main() { group('writeTimelineToFile', () { - Directory tempDir; + late Directory tempDir; setUp(() { useMemoryFileSystemForTesting(); @@ -480,7 +478,7 @@ void main() { final Timeline timeline = Timeline.fromJson({ 'traceEvents': traceEvents, }); - return SceneDisplayLagSummarizer(timeline.events); + return SceneDisplayLagSummarizer(timeline.events!); } test('average_vsyncs_missed', () async { @@ -531,7 +529,7 @@ void main() { final Timeline timeline = Timeline.fromJson({ 'traceEvents': traceEvents, }); - return ProfilingSummarizer.fromEvents(timeline.events); + return ProfilingSummarizer.fromEvents(timeline.events!); } test('has_both_cpu_and_memory_usage', () async { diff --git a/packages/flutter_driver/test/src/real_tests/timeline_test.dart b/packages/flutter_driver/test/src/real_tests/timeline_test.dart index 40f7cd9406..b3ef0eb8de 100644 --- a/packages/flutter_driver/test/src/real_tests/timeline_test.dart +++ b/packages/flutter_driver/test/src/real_tests/timeline_test.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import 'package:flutter_driver/src/driver/timeline.dart'; import '../../common.dart'; @@ -34,7 +32,7 @@ void main() { expect(timeline.events, hasLength(2)); - final TimelineEvent e1 = timeline.events[1]; + final TimelineEvent e1 = timeline.events![1]; expect(e1.name, 'test event'); expect(e1.category, 'test category'); expect(e1.phase, 'B'); @@ -46,7 +44,7 @@ void main() { expect(e1.threadTimestampMicros, 567); expect(e1.arguments, {'arg1': true}); - final TimelineEvent e2 = timeline.events[0]; + final TimelineEvent e2 = timeline.events![0]; expect(e2.name, isNull); expect(e2.category, isNull); expect(e2.phase, isNull); @@ -74,10 +72,10 @@ void main() { }); expect(timeline.events, hasLength(2)); - expect(timeline.events[0].timestampMicros, equals(456)); - expect(timeline.events[1].timestampMicros, equals(457)); - expect(timeline.events[0].name, equals('test event 2')); - expect(timeline.events[1].name, equals('test event 1')); + expect(timeline.events![0].timestampMicros, equals(456)); + expect(timeline.events![1].timestampMicros, equals(457)); + expect(timeline.events![0].name, equals('test event 2')); + expect(timeline.events![1].name, equals('test event 1')); }); test('sorts JSON nulls first', () { @@ -103,14 +101,14 @@ void main() { }); expect(timeline.events, hasLength(4)); - expect(timeline.events[0].timestampMicros, isNull); - expect(timeline.events[1].timestampMicros, isNull); - expect(timeline.events[2].timestampMicros, equals(456)); - expect(timeline.events[3].timestampMicros, equals(457)); - expect(timeline.events[0].name, equals('test event 0')); - expect(timeline.events[1].name, equals('test event 3')); - expect(timeline.events[2].name, equals('test event 2')); - expect(timeline.events[3].name, equals('test event 1')); + expect(timeline.events![0].timestampMicros, isNull); + expect(timeline.events![1].timestampMicros, isNull); + expect(timeline.events![2].timestampMicros, equals(456)); + expect(timeline.events![3].timestampMicros, equals(457)); + expect(timeline.events![0].name, equals('test event 0')); + expect(timeline.events![1].name, equals('test event 3')); + expect(timeline.events![2].name, equals('test event 2')); + expect(timeline.events![3].name, equals('test event 1')); }); }); } diff --git a/packages/flutter_driver/test/src/real_tests/wait_test.dart b/packages/flutter_driver/test/src/real_tests/wait_test.dart index 5526b86422..adf99a45e8 100644 --- a/packages/flutter_driver/test/src/real_tests/wait_test.dart +++ b/packages/flutter_driver/test/src/real_tests/wait_test.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import 'package:flutter_driver/src/common/wait.dart'; import '../../common.dart'; diff --git a/packages/flutter_driver/test_driver/failure.dart b/packages/flutter_driver/test_driver/failure.dart index 935a022a83..66b76f9d90 100644 --- a/packages/flutter_driver/test_driver/failure.dart +++ b/packages/flutter_driver/test_driver/failure.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import 'package:flutter_driver/driver_extension.dart'; void main() { diff --git a/packages/flutter_driver/test_driver/failure_test.dart b/packages/flutter_driver/test_driver/failure_test.dart index 4e98f41d84..c5a7f6ea00 100644 --- a/packages/flutter_driver/test_driver/failure_test.dart +++ b/packages/flutter_driver/test_driver/failure_test.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import '../test/common.dart'; void main() { diff --git a/packages/flutter_driver/test_driver/success.dart b/packages/flutter_driver/test_driver/success.dart index 935a022a83..66b76f9d90 100644 --- a/packages/flutter_driver/test_driver/success.dart +++ b/packages/flutter_driver/test_driver/success.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import 'package:flutter_driver/driver_extension.dart'; void main() { diff --git a/packages/flutter_driver/test_driver/success_test.dart b/packages/flutter_driver/test_driver/success_test.dart index 399e82d2ed..bd811f537b 100644 --- a/packages/flutter_driver/test_driver/success_test.dart +++ b/packages/flutter_driver/test_driver/success_test.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import '../test/common.dart'; void main() {