Reland "[null-safety] reland: migrate app side flutter driver to null-safety" (#67570)
This commit is contained in:
parent
1bcaf94062
commit
4f2fcca6a9
@ -10,4 +10,4 @@ analyzer:
|
|||||||
type_init_formals: false # https://github.com/dart-lang/linter/issues/2192
|
type_init_formals: false # https://github.com/dart-lang/linter/issues/2192
|
||||||
unrelated_type_equality_checks: false # https://github.com/dart-lang/linter/issues/2196
|
unrelated_type_equality_checks: false # https://github.com/dart-lang/linter/issues/2196
|
||||||
void_checks: false # https://github.com/dart-lang/linter/issues/2185
|
void_checks: false # https://github.com/dart-lang/linter/issues/2185
|
||||||
unnecessary_null_comparison: false # https://github.com/dart-lang/language/issues/1018 , turned off until https://github.com/flutter/flutter/issues/61042
|
unnecessary_null_comparison: false # Turned off until null-safe rollout is complete.
|
||||||
|
13
packages/flutter_driver/analysis_options.yaml
Normal file
13
packages/flutter_driver/analysis_options.yaml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Use the parent analysis options settings and enable null-experiment.
|
||||||
|
|
||||||
|
include: ../analysis_options.yaml
|
||||||
|
|
||||||
|
analyzer:
|
||||||
|
enable-experiment:
|
||||||
|
- non-nullable
|
||||||
|
errors:
|
||||||
|
always_require_non_null_named_parameters: false # not needed with nnbd
|
||||||
|
type_init_formals: false # https://github.com/dart-lang/linter/issues/2192
|
||||||
|
unrelated_type_equality_checks: false # https://github.com/dart-lang/linter/issues/2196
|
||||||
|
void_checks: false # https://github.com/dart-lang/linter/issues/2185
|
||||||
|
unnecessary_null_comparison: false # Turned off until null-safe rollout is complete.
|
@ -2,6 +2,8 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// @dart = 2.8
|
||||||
|
|
||||||
/// Provides API to test Flutter applications that run on real
|
/// Provides API to test Flutter applications that run on real
|
||||||
/// devices and emulators.
|
/// devices and emulators.
|
||||||
///
|
///
|
||||||
|
@ -27,16 +27,16 @@ class GetDiagnosticsTree extends CommandWithTarget {
|
|||||||
GetDiagnosticsTree(SerializableFinder finder, this.diagnosticsType, {
|
GetDiagnosticsTree(SerializableFinder finder, this.diagnosticsType, {
|
||||||
this.subtreeDepth = 0,
|
this.subtreeDepth = 0,
|
||||||
this.includeProperties = true,
|
this.includeProperties = true,
|
||||||
Duration timeout,
|
Duration? timeout,
|
||||||
}) : assert(subtreeDepth != null),
|
}) : assert(subtreeDepth != null),
|
||||||
assert(includeProperties != null),
|
assert(includeProperties != null),
|
||||||
super(finder, timeout: timeout);
|
super(finder, timeout: timeout);
|
||||||
|
|
||||||
/// Deserializes this command from the value generated by [serialize].
|
/// Deserializes this command from the value generated by [serialize].
|
||||||
GetDiagnosticsTree.deserialize(Map<String, String> json, DeserializeFinderFactory finderFactory)
|
GetDiagnosticsTree.deserialize(Map<String, String> json, DeserializeFinderFactory finderFactory)
|
||||||
: subtreeDepth = int.parse(json['subtreeDepth']),
|
: subtreeDepth = int.parse(json['subtreeDepth']!),
|
||||||
includeProperties = json['includeProperties'] == 'true',
|
includeProperties = json['includeProperties'] == 'true',
|
||||||
diagnosticsType = _diagnosticsTypeIndex.lookupBySimpleName(json['diagnosticsType']),
|
diagnosticsType = _diagnosticsTypeIndex.lookupBySimpleName(json['diagnosticsType']!),
|
||||||
super.deserialize(json, finderFactory);
|
super.deserialize(json, finderFactory);
|
||||||
|
|
||||||
/// How many levels of children to include in the JSON result.
|
/// How many levels of children to include in the JSON result.
|
||||||
@ -69,7 +69,7 @@ class DiagnosticsTreeResult extends Result {
|
|||||||
|
|
||||||
/// The JSON encoded [DiagnosticsNode] tree requested by the
|
/// The JSON encoded [DiagnosticsNode] tree requested by the
|
||||||
/// [GetDiagnosticsTree] command.
|
/// [GetDiagnosticsTree] command.
|
||||||
final Map<String, Object> json;
|
final Map<String, dynamic> json;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, dynamic> toJson() => json;
|
Map<String, dynamic> toJson() => json;
|
||||||
|
@ -31,10 +31,10 @@ class EnumIndex<E> {
|
|||||||
final Map<E, String> _valueToName;
|
final Map<E, String> _valueToName;
|
||||||
|
|
||||||
/// Given a [simpleName] finds the corresponding enum value.
|
/// Given a [simpleName] finds the corresponding enum value.
|
||||||
E lookupBySimpleName(String simpleName) => _nameToValue[simpleName];
|
E lookupBySimpleName(String simpleName) => _nameToValue[simpleName]!;
|
||||||
|
|
||||||
/// Returns the simple name for [enumValue].
|
/// Returns the simple name for [enumValue].
|
||||||
String toSimpleName(E enumValue) => _valueToName[enumValue];
|
String toSimpleName(E enumValue) => _valueToName[enumValue]!;
|
||||||
}
|
}
|
||||||
|
|
||||||
String _getSimpleName(dynamic enumValue) {
|
String _getSimpleName(dynamic enumValue) {
|
||||||
|
@ -13,7 +13,7 @@ import 'message.dart';
|
|||||||
mixin DeserializeFinderFactory {
|
mixin DeserializeFinderFactory {
|
||||||
/// Deserializes the finder from JSON generated by [SerializableFinder.serialize].
|
/// Deserializes the finder from JSON generated by [SerializableFinder.serialize].
|
||||||
SerializableFinder deserializeFinder(Map<String, String> json) {
|
SerializableFinder deserializeFinder(Map<String, String> json) {
|
||||||
final String finderType = json['finderType'];
|
final String? finderType = json['finderType'];
|
||||||
switch (finderType) {
|
switch (finderType) {
|
||||||
case 'ByType': return ByType.deserialize(json);
|
case 'ByType': return ByType.deserialize(json);
|
||||||
case 'ByValueKey': return ByValueKey.deserialize(json);
|
case 'ByValueKey': return ByValueKey.deserialize(json);
|
||||||
@ -41,7 +41,7 @@ DriverError _createInvalidKeyValueTypeError(String invalidType) {
|
|||||||
/// and add more keys to the returned map.
|
/// and add more keys to the returned map.
|
||||||
abstract class CommandWithTarget extends Command {
|
abstract class CommandWithTarget extends Command {
|
||||||
/// Constructs this command given a [finder].
|
/// Constructs this command given a [finder].
|
||||||
CommandWithTarget(this.finder, {Duration timeout}) : super(timeout: timeout) {
|
CommandWithTarget(this.finder, {Duration? timeout}) : super(timeout: timeout) {
|
||||||
assert(finder != null, '$runtimeType target cannot be null');
|
assert(finder != null, '$runtimeType target cannot be null');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ class WaitFor extends CommandWithTarget {
|
|||||||
/// appear within the [timeout] amount of time.
|
/// appear within the [timeout] amount of time.
|
||||||
///
|
///
|
||||||
/// If [timeout] is not specified, the command defaults to no timeout.
|
/// If [timeout] is not specified, the command defaults to no timeout.
|
||||||
WaitFor(SerializableFinder finder, {Duration timeout})
|
WaitFor(SerializableFinder finder, {Duration? timeout})
|
||||||
: super(finder, timeout: timeout);
|
: super(finder, timeout: timeout);
|
||||||
|
|
||||||
/// Deserializes this command from the value generated by [serialize].
|
/// Deserializes this command from the value generated by [serialize].
|
||||||
@ -102,7 +102,7 @@ class WaitForAbsent extends CommandWithTarget {
|
|||||||
/// disappear within the [timeout] amount of time.
|
/// disappear within the [timeout] amount of time.
|
||||||
///
|
///
|
||||||
/// If [timeout] is not specified, the command defaults to no timeout.
|
/// If [timeout] is not specified, the command defaults to no timeout.
|
||||||
WaitForAbsent(SerializableFinder finder, {Duration timeout})
|
WaitForAbsent(SerializableFinder finder, {Duration? timeout})
|
||||||
: super(finder, timeout: timeout);
|
: super(finder, timeout: timeout);
|
||||||
|
|
||||||
/// Deserializes this command from the value generated by [serialize].
|
/// Deserializes this command from the value generated by [serialize].
|
||||||
@ -164,7 +164,7 @@ class ByTooltipMessage extends SerializableFinder {
|
|||||||
|
|
||||||
/// Deserializes the finder from JSON generated by [serialize].
|
/// Deserializes the finder from JSON generated by [serialize].
|
||||||
static ByTooltipMessage deserialize(Map<String, String> json) {
|
static ByTooltipMessage deserialize(Map<String, String> json) {
|
||||||
return ByTooltipMessage(json['text']);
|
return ByTooltipMessage(json['text']!);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,7 +202,7 @@ class BySemanticsLabel extends SerializableFinder {
|
|||||||
/// Deserializes the finder from JSON generated by [serialize].
|
/// Deserializes the finder from JSON generated by [serialize].
|
||||||
static BySemanticsLabel deserialize(Map<String, String> json) {
|
static BySemanticsLabel deserialize(Map<String, String> json) {
|
||||||
final bool isRegExp = json['isRegExp'] == 'true';
|
final bool isRegExp = json['isRegExp'] == 'true';
|
||||||
return BySemanticsLabel(isRegExp ? RegExp(json['label']) : json['label']);
|
return BySemanticsLabel(isRegExp ? RegExp(json['label']!) : json['label']!);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,7 +225,7 @@ class ByText extends SerializableFinder {
|
|||||||
|
|
||||||
/// Deserializes the finder from JSON generated by [serialize].
|
/// Deserializes the finder from JSON generated by [serialize].
|
||||||
static ByText deserialize(Map<String, String> json) {
|
static ByText deserialize(Map<String, String> json) {
|
||||||
return ByText(json['text']);
|
return ByText(json['text']!);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,8 +261,8 @@ class ByValueKey extends SerializableFinder {
|
|||||||
|
|
||||||
/// Deserializes the finder from JSON generated by [serialize].
|
/// Deserializes the finder from JSON generated by [serialize].
|
||||||
static ByValueKey deserialize(Map<String, String> json) {
|
static ByValueKey deserialize(Map<String, String> json) {
|
||||||
final String keyValueString = json['keyValueString'];
|
final String keyValueString = json['keyValueString']!;
|
||||||
final String keyValueType = json['keyValueType'];
|
final String keyValueType = json['keyValueType']!;
|
||||||
switch (keyValueType) {
|
switch (keyValueType) {
|
||||||
case 'int':
|
case 'int':
|
||||||
return ByValueKey(int.parse(keyValueString));
|
return ByValueKey(int.parse(keyValueString));
|
||||||
@ -292,7 +292,7 @@ class ByType extends SerializableFinder {
|
|||||||
|
|
||||||
/// Deserializes the finder from JSON generated by [serialize].
|
/// Deserializes the finder from JSON generated by [serialize].
|
||||||
static ByType deserialize(Map<String, String> json) {
|
static ByType deserialize(Map<String, String> json) {
|
||||||
return ByType(json['type']);
|
return ByType(json['type']!);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,8 +318,8 @@ class PageBack extends SerializableFinder {
|
|||||||
class Descendant extends SerializableFinder {
|
class Descendant extends SerializableFinder {
|
||||||
/// Creates a descendant finder.
|
/// Creates a descendant finder.
|
||||||
const Descendant({
|
const Descendant({
|
||||||
@required this.of,
|
required this.of,
|
||||||
@required this.matching,
|
required this.matching,
|
||||||
this.matchRoot = false,
|
this.matchRoot = false,
|
||||||
this.firstMatchOnly = false,
|
this.firstMatchOnly = false,
|
||||||
});
|
});
|
||||||
@ -353,9 +353,9 @@ class Descendant extends SerializableFinder {
|
|||||||
/// Deserializes the finder from JSON generated by [serialize].
|
/// Deserializes the finder from JSON generated by [serialize].
|
||||||
static Descendant deserialize(Map<String, String> json, DeserializeFinderFactory finderFactory) {
|
static Descendant deserialize(Map<String, String> json, DeserializeFinderFactory finderFactory) {
|
||||||
final Map<String, String> jsonOfMatcher =
|
final Map<String, String> jsonOfMatcher =
|
||||||
Map<String, String>.from(jsonDecode(json['of']) as Map<String, dynamic>);
|
Map<String, String>.from(jsonDecode(json['of']!) as Map<String, dynamic>);
|
||||||
final Map<String, String> jsonMatchingMatcher =
|
final Map<String, String> jsonMatchingMatcher =
|
||||||
Map<String, String>.from(jsonDecode(json['matching']) as Map<String, dynamic>);
|
Map<String, String>.from(jsonDecode(json['matching']!) as Map<String, dynamic>);
|
||||||
return Descendant(
|
return Descendant(
|
||||||
of: finderFactory.deserializeFinder(jsonOfMatcher),
|
of: finderFactory.deserializeFinder(jsonOfMatcher),
|
||||||
matching: finderFactory.deserializeFinder(jsonMatchingMatcher),
|
matching: finderFactory.deserializeFinder(jsonMatchingMatcher),
|
||||||
@ -373,8 +373,8 @@ class Descendant extends SerializableFinder {
|
|||||||
class Ancestor extends SerializableFinder {
|
class Ancestor extends SerializableFinder {
|
||||||
/// Creates an ancestor finder.
|
/// Creates an ancestor finder.
|
||||||
const Ancestor({
|
const Ancestor({
|
||||||
@required this.of,
|
required this.of,
|
||||||
@required this.matching,
|
required this.matching,
|
||||||
this.matchRoot = false,
|
this.matchRoot = false,
|
||||||
this.firstMatchOnly = false,
|
this.firstMatchOnly = false,
|
||||||
});
|
});
|
||||||
@ -408,9 +408,9 @@ class Ancestor extends SerializableFinder {
|
|||||||
/// Deserializes the finder from JSON generated by [serialize].
|
/// Deserializes the finder from JSON generated by [serialize].
|
||||||
static Ancestor deserialize(Map<String, String> json, DeserializeFinderFactory finderFactory) {
|
static Ancestor deserialize(Map<String, String> json, DeserializeFinderFactory finderFactory) {
|
||||||
final Map<String, String> jsonOfMatcher =
|
final Map<String, String> jsonOfMatcher =
|
||||||
Map<String, String>.from(jsonDecode(json['of']) as Map<String, dynamic>);
|
Map<String, String>.from(jsonDecode(json['of']!) as Map<String, dynamic>);
|
||||||
final Map<String, String> jsonMatchingMatcher =
|
final Map<String, String> jsonMatchingMatcher =
|
||||||
Map<String, String>.from(jsonDecode(json['matching']) as Map<String, dynamic>);
|
Map<String, String>.from(jsonDecode(json['matching']!) as Map<String, dynamic>);
|
||||||
return Ancestor(
|
return Ancestor(
|
||||||
of: finderFactory.deserializeFinder(jsonOfMatcher),
|
of: finderFactory.deserializeFinder(jsonOfMatcher),
|
||||||
matching: finderFactory.deserializeFinder(jsonMatchingMatcher),
|
matching: finderFactory.deserializeFinder(jsonMatchingMatcher),
|
||||||
@ -435,7 +435,7 @@ class Ancestor extends SerializableFinder {
|
|||||||
class GetSemanticsId extends CommandWithTarget {
|
class GetSemanticsId extends CommandWithTarget {
|
||||||
|
|
||||||
/// Creates a command which finds a Widget and then looks up the semantic id.
|
/// Creates a command which finds a Widget and then looks up the semantic id.
|
||||||
GetSemanticsId(SerializableFinder finder, {Duration timeout}) : super(finder, timeout: timeout);
|
GetSemanticsId(SerializableFinder finder, {Duration? timeout}) : super(finder, timeout: timeout);
|
||||||
|
|
||||||
/// Creates a command from a JSON map.
|
/// Creates a command from a JSON map.
|
||||||
GetSemanticsId.deserialize(Map<String, String> json, DeserializeFinderFactory finderFactory)
|
GetSemanticsId.deserialize(Map<String, String> json, DeserializeFinderFactory finderFactory)
|
||||||
|
@ -7,11 +7,11 @@ import 'message.dart';
|
|||||||
/// A Flutter Driver command that enables or disables the FrameSync mechanism.
|
/// A Flutter Driver command that enables or disables the FrameSync mechanism.
|
||||||
class SetFrameSync extends Command {
|
class SetFrameSync extends Command {
|
||||||
/// Creates a command to toggle the FrameSync mechanism.
|
/// Creates a command to toggle the FrameSync mechanism.
|
||||||
const SetFrameSync(this.enabled, { Duration timeout }) : super(timeout: timeout);
|
const SetFrameSync(this.enabled, { Duration? timeout }) : super(timeout: timeout);
|
||||||
|
|
||||||
/// Deserializes this command from the value generated by [serialize].
|
/// Deserializes this command from the value generated by [serialize].
|
||||||
SetFrameSync.deserialize(Map<String, String> params)
|
SetFrameSync.deserialize(Map<String, String> params)
|
||||||
: enabled = params['enabled'].toLowerCase() == 'true',
|
: enabled = params['enabled']!.toLowerCase() == 'true',
|
||||||
super.deserialize(params);
|
super.deserialize(params);
|
||||||
|
|
||||||
/// Whether frameSync should be enabled or disabled.
|
/// Whether frameSync should be enabled or disabled.
|
||||||
|
@ -2,10 +2,11 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// @dart = 2.8
|
||||||
|
|
||||||
/// Convenience methods for Flutter application driving on Fuchsia. Can
|
/// Convenience methods for Flutter application driving on Fuchsia. Can
|
||||||
/// be run on either a host machine (making a remote connection to a Fuchsia
|
/// be run on either a host machine (making a remote connection to a Fuchsia
|
||||||
/// device), or on the target Fuchsia machine.
|
/// device), or on the target Fuchsia machine.
|
||||||
import 'dart:core';
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:fuchsia_remote_debug_protocol/fuchsia_remote_debug_protocol.dart';
|
import 'package:fuchsia_remote_debug_protocol/fuchsia_remote_debug_protocol.dart';
|
||||||
|
@ -33,11 +33,11 @@ EnumIndex<OffsetType> _offsetTypeIndex = EnumIndex<OffsetType>(OffsetType.values
|
|||||||
/// to device pixels via [Window.devicePixelRatio].
|
/// to device pixels via [Window.devicePixelRatio].
|
||||||
class GetOffset extends CommandWithTarget {
|
class GetOffset extends CommandWithTarget {
|
||||||
/// The `finder` looks for an element to get its rect.
|
/// The `finder` looks for an element to get its rect.
|
||||||
GetOffset(SerializableFinder finder, this.offsetType, { Duration timeout }) : super(finder, timeout: timeout);
|
GetOffset(SerializableFinder finder, this.offsetType, { Duration? timeout }) : super(finder, timeout: timeout);
|
||||||
|
|
||||||
/// Deserializes this command from the value generated by [serialize].
|
/// Deserializes this command from the value generated by [serialize].
|
||||||
GetOffset.deserialize(Map<String, String> json, DeserializeFinderFactory finderFactory)
|
GetOffset.deserialize(Map<String, String> json, DeserializeFinderFactory finderFactory)
|
||||||
: offsetType = _offsetTypeIndex.lookupBySimpleName(json['offsetType']),
|
: offsetType = _offsetTypeIndex.lookupBySimpleName(json['offsetType']!),
|
||||||
super.deserialize(json, finderFactory);
|
super.deserialize(json, finderFactory);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -8,7 +8,7 @@ import 'message.dart';
|
|||||||
/// A Flutter Driver command that taps on a target widget located by [finder].
|
/// A Flutter Driver command that taps on a target widget located by [finder].
|
||||||
class Tap extends CommandWithTarget {
|
class Tap extends CommandWithTarget {
|
||||||
/// Creates a tap command to tap on a widget located by [finder].
|
/// Creates a tap command to tap on a widget located by [finder].
|
||||||
Tap(SerializableFinder finder, { Duration timeout }) : super(finder, timeout: timeout);
|
Tap(SerializableFinder finder, { Duration? timeout }) : super(finder, timeout: timeout);
|
||||||
|
|
||||||
/// Deserializes this command from the value generated by [serialize].
|
/// Deserializes this command from the value generated by [serialize].
|
||||||
Tap.deserialize(Map<String, String> json, DeserializeFinderFactory finderFactory) : super.deserialize(json, finderFactory);
|
Tap.deserialize(Map<String, String> json, DeserializeFinderFactory finderFactory) : super.deserialize(json, finderFactory);
|
||||||
@ -42,15 +42,15 @@ class Scroll extends CommandWithTarget {
|
|||||||
this.dy,
|
this.dy,
|
||||||
this.duration,
|
this.duration,
|
||||||
this.frequency, {
|
this.frequency, {
|
||||||
Duration timeout,
|
Duration? timeout,
|
||||||
}) : super(finder, timeout: timeout);
|
}) : super(finder, timeout: timeout);
|
||||||
|
|
||||||
/// Deserializes this command from the value generated by [serialize].
|
/// Deserializes this command from the value generated by [serialize].
|
||||||
Scroll.deserialize(Map<String, String> json, DeserializeFinderFactory finderFactory)
|
Scroll.deserialize(Map<String, String> json, DeserializeFinderFactory finderFactory)
|
||||||
: dx = double.parse(json['dx']),
|
: dx = double.parse(json['dx']!),
|
||||||
dy = double.parse(json['dy']),
|
dy = double.parse(json['dy']!),
|
||||||
duration = Duration(microseconds: int.parse(json['duration'])),
|
duration = Duration(microseconds: int.parse(json['duration']!)),
|
||||||
frequency = int.parse(json['frequency']),
|
frequency = int.parse(json['frequency']!),
|
||||||
super.deserialize(json, finderFactory);
|
super.deserialize(json, finderFactory);
|
||||||
|
|
||||||
/// Delta X offset per move event.
|
/// Delta X offset per move event.
|
||||||
@ -96,11 +96,11 @@ class ScrollResult extends Result {
|
|||||||
class ScrollIntoView extends CommandWithTarget {
|
class ScrollIntoView extends CommandWithTarget {
|
||||||
/// Creates this command given a [finder] used to locate the widget to be
|
/// Creates this command given a [finder] used to locate the widget to be
|
||||||
/// scrolled into view.
|
/// scrolled into view.
|
||||||
ScrollIntoView(SerializableFinder finder, { this.alignment = 0.0, Duration timeout }) : super(finder, timeout: timeout);
|
ScrollIntoView(SerializableFinder finder, { this.alignment = 0.0, Duration? timeout }) : super(finder, timeout: timeout);
|
||||||
|
|
||||||
/// Deserializes this command from the value generated by [serialize].
|
/// Deserializes this command from the value generated by [serialize].
|
||||||
ScrollIntoView.deserialize(Map<String, String> json, DeserializeFinderFactory finderFactory)
|
ScrollIntoView.deserialize(Map<String, String> json, DeserializeFinderFactory finderFactory)
|
||||||
: alignment = double.parse(json['alignment']),
|
: alignment = double.parse(json['alignment']!),
|
||||||
super.deserialize(json, finderFactory);
|
super.deserialize(json, finderFactory);
|
||||||
|
|
||||||
/// How the widget should be aligned.
|
/// How the widget should be aligned.
|
||||||
|
@ -8,7 +8,7 @@ import 'message.dart';
|
|||||||
/// A Flutter Driver command that requests an application health check.
|
/// A Flutter Driver command that requests an application health check.
|
||||||
class GetHealth extends Command {
|
class GetHealth extends Command {
|
||||||
/// Create a health check command.
|
/// Create a health check command.
|
||||||
const GetHealth({ Duration timeout }) : super(timeout: timeout);
|
const GetHealth({ Duration? timeout }) : super(timeout: timeout);
|
||||||
|
|
||||||
/// Deserializes this command from the value generated by [serialize].
|
/// Deserializes this command from the value generated by [serialize].
|
||||||
GetHealth.deserialize(Map<String, String> json) : super.deserialize(json);
|
GetHealth.deserialize(Map<String, String> json) : super.deserialize(json);
|
||||||
|
@ -7,7 +7,7 @@ import 'message.dart';
|
|||||||
/// A Flutter Driver command that requests a string representation of the layer tree.
|
/// A Flutter Driver command that requests a string representation of the layer tree.
|
||||||
class GetLayerTree extends Command {
|
class GetLayerTree extends Command {
|
||||||
/// Create a command to request a string representation of the layer tree.
|
/// Create a command to request a string representation of the layer tree.
|
||||||
const GetLayerTree({ Duration timeout }) : super(timeout: timeout);
|
const GetLayerTree({ Duration? timeout }) : super(timeout: timeout);
|
||||||
|
|
||||||
/// Deserializes this command from the value generated by [serialize].
|
/// Deserializes this command from the value generated by [serialize].
|
||||||
GetLayerTree.deserialize(Map<String, String> json) : super.deserialize(json);
|
GetLayerTree.deserialize(Map<String, String> json) : super.deserialize(json);
|
||||||
@ -23,7 +23,7 @@ class LayerTree extends Result {
|
|||||||
const LayerTree(this.tree);
|
const LayerTree(this.tree);
|
||||||
|
|
||||||
/// String representation of the layer tree.
|
/// String representation of the layer tree.
|
||||||
final String tree;
|
final String? tree;
|
||||||
|
|
||||||
/// Deserializes the result from JSON.
|
/// Deserializes the result from JSON.
|
||||||
static LayerTree fromJson(Map<String, dynamic> json) {
|
static LayerTree fromJson(Map<String, dynamic> json) {
|
||||||
|
@ -15,8 +15,8 @@ abstract class Command {
|
|||||||
Command.deserialize(Map<String, String> json)
|
Command.deserialize(Map<String, String> json)
|
||||||
: timeout = _parseTimeout(json);
|
: timeout = _parseTimeout(json);
|
||||||
|
|
||||||
static Duration _parseTimeout(Map<String, String> json) {
|
static Duration? _parseTimeout(Map<String, String> json) {
|
||||||
final String timeout = json['timeout'];
|
final String? timeout = json['timeout'];
|
||||||
if (timeout == null)
|
if (timeout == null)
|
||||||
return null;
|
return null;
|
||||||
return Duration(milliseconds: int.parse(timeout));
|
return Duration(milliseconds: int.parse(timeout));
|
||||||
@ -27,7 +27,7 @@ abstract class Command {
|
|||||||
/// Defaults to no timeout, because it is common for operations to take oddly
|
/// Defaults to no timeout, because it is common for operations to take oddly
|
||||||
/// long in test environments (e.g. because the test host is overloaded), and
|
/// long in test environments (e.g. because the test host is overloaded), and
|
||||||
/// having timeouts essentially means having race conditions.
|
/// having timeouts essentially means having race conditions.
|
||||||
final Duration timeout;
|
final Duration? timeout;
|
||||||
|
|
||||||
/// Identifies the type of the command object and of the handler.
|
/// Identifies the type of the command object and of the handler.
|
||||||
String get kind;
|
String get kind;
|
||||||
@ -53,7 +53,7 @@ abstract class Command {
|
|||||||
'command': kind,
|
'command': kind,
|
||||||
};
|
};
|
||||||
if (timeout != null)
|
if (timeout != null)
|
||||||
result['timeout'] = '${timeout.inMilliseconds}';
|
result['timeout'] = '${timeout!.inMilliseconds}';
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import 'message.dart';
|
|||||||
/// A Flutter Driver command that requests a string representation of the render tree.
|
/// A Flutter Driver command that requests a string representation of the render tree.
|
||||||
class GetRenderTree extends Command {
|
class GetRenderTree extends Command {
|
||||||
/// Create a command to request a string representation of the render tree.
|
/// Create a command to request a string representation of the render tree.
|
||||||
const GetRenderTree({ Duration timeout }) : super(timeout: timeout);
|
const GetRenderTree({ Duration? timeout }) : super(timeout: timeout);
|
||||||
|
|
||||||
/// Deserializes this command from the value generated by [serialize].
|
/// Deserializes this command from the value generated by [serialize].
|
||||||
GetRenderTree.deserialize(Map<String, String> json) : super.deserialize(json);
|
GetRenderTree.deserialize(Map<String, String> json) : super.deserialize(json);
|
||||||
@ -23,7 +23,7 @@ class RenderTree extends Result {
|
|||||||
const RenderTree(this.tree);
|
const RenderTree(this.tree);
|
||||||
|
|
||||||
/// String representation of the render tree.
|
/// String representation of the render tree.
|
||||||
final String tree;
|
final String? tree;
|
||||||
|
|
||||||
/// Deserializes the result from JSON.
|
/// Deserializes the result from JSON.
|
||||||
static RenderTree fromJson(Map<String, dynamic> json) {
|
static RenderTree fromJson(Map<String, dynamic> json) {
|
||||||
|
@ -8,7 +8,7 @@ import 'message.dart';
|
|||||||
/// string response.
|
/// string response.
|
||||||
class RequestData extends Command {
|
class RequestData extends Command {
|
||||||
/// Create a command that sends a message.
|
/// Create a command that sends a message.
|
||||||
const RequestData(this.message, { Duration timeout }) : super(timeout: timeout);
|
const RequestData(this.message, { Duration? timeout }) : super(timeout: timeout);
|
||||||
|
|
||||||
/// Deserializes this command from the value generated by [serialize].
|
/// Deserializes this command from the value generated by [serialize].
|
||||||
RequestData.deserialize(Map<String, String> params)
|
RequestData.deserialize(Map<String, String> params)
|
||||||
@ -16,7 +16,7 @@ class RequestData extends Command {
|
|||||||
super.deserialize(params);
|
super.deserialize(params);
|
||||||
|
|
||||||
/// The message being sent from the test to the application.
|
/// The message being sent from the test to the application.
|
||||||
final String message;
|
final String? message;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get kind => 'request_data';
|
String get kind => 'request_data';
|
||||||
@ -26,7 +26,8 @@ class RequestData extends Command {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, String> serialize() => super.serialize()..addAll(<String, String>{
|
Map<String, String> serialize() => super.serialize()..addAll(<String, String>{
|
||||||
'message': message,
|
if (message != null)
|
||||||
|
'message': message!,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,11 +7,11 @@ import 'message.dart';
|
|||||||
/// A Flutter Driver command that enables or disables semantics.
|
/// A Flutter Driver command that enables or disables semantics.
|
||||||
class SetSemantics extends Command {
|
class SetSemantics extends Command {
|
||||||
/// Creates a command that enables or disables semantics.
|
/// Creates a command that enables or disables semantics.
|
||||||
const SetSemantics(this.enabled, { Duration timeout }) : super(timeout: timeout);
|
const SetSemantics(this.enabled, { Duration? timeout }) : super(timeout: timeout);
|
||||||
|
|
||||||
/// Deserializes this command from the value generated by [serialize].
|
/// Deserializes this command from the value generated by [serialize].
|
||||||
SetSemantics.deserialize(Map<String, String> params)
|
SetSemantics.deserialize(Map<String, String> params)
|
||||||
: enabled = params['enabled'].toLowerCase() == 'true',
|
: enabled = params['enabled']!.toLowerCase() == 'true',
|
||||||
super.deserialize(params);
|
super.deserialize(params);
|
||||||
|
|
||||||
/// Whether semantics should be enabled (true) or disabled (false).
|
/// Whether semantics should be enabled (true) or disabled (false).
|
||||||
|
@ -8,7 +8,7 @@ import 'message.dart';
|
|||||||
/// A Flutter Driver command that reads the text from a given element.
|
/// A Flutter Driver command that reads the text from a given element.
|
||||||
class GetText extends CommandWithTarget {
|
class GetText extends CommandWithTarget {
|
||||||
/// [finder] looks for an element that contains a piece of text.
|
/// [finder] looks for an element that contains a piece of text.
|
||||||
GetText(SerializableFinder finder, { Duration timeout }) : super(finder, timeout: timeout);
|
GetText(SerializableFinder finder, { Duration? timeout }) : super(finder, timeout: timeout);
|
||||||
|
|
||||||
/// Deserializes this command from the value generated by [serialize].
|
/// Deserializes this command from the value generated by [serialize].
|
||||||
GetText.deserialize(Map<String, String> json, DeserializeFinderFactory finderFactory) : super.deserialize(json, finderFactory);
|
GetText.deserialize(Map<String, String> json, DeserializeFinderFactory finderFactory) : super.deserialize(json, finderFactory);
|
||||||
@ -39,11 +39,11 @@ class GetTextResult extends Result {
|
|||||||
/// A Flutter Driver command that enters text into the currently focused widget.
|
/// A Flutter Driver command that enters text into the currently focused widget.
|
||||||
class EnterText extends Command {
|
class EnterText extends Command {
|
||||||
/// Creates a command that enters text into the currently focused widget.
|
/// Creates a command that enters text into the currently focused widget.
|
||||||
const EnterText(this.text, { Duration timeout }) : super(timeout: timeout);
|
const EnterText(this.text, { Duration? timeout }) : super(timeout: timeout);
|
||||||
|
|
||||||
/// Deserializes this command from the value generated by [serialize].
|
/// Deserializes this command from the value generated by [serialize].
|
||||||
EnterText.deserialize(Map<String, String> json)
|
EnterText.deserialize(Map<String, String> json)
|
||||||
: text = json['text'],
|
: text = json['text']!,
|
||||||
super.deserialize(json);
|
super.deserialize(json);
|
||||||
|
|
||||||
/// The text extracted by the [GetText] command.
|
/// The text extracted by the [GetText] command.
|
||||||
@ -75,7 +75,7 @@ class EnterTextResult extends Result {
|
|||||||
/// A Flutter Driver command that enables and disables text entry emulation.
|
/// A Flutter Driver command that enables and disables text entry emulation.
|
||||||
class SetTextEntryEmulation extends Command {
|
class SetTextEntryEmulation extends Command {
|
||||||
/// Creates a command that enables and disables text entry emulation.
|
/// Creates a command that enables and disables text entry emulation.
|
||||||
const SetTextEntryEmulation(this.enabled, { Duration timeout }) : super(timeout: timeout);
|
const SetTextEntryEmulation(this.enabled, { Duration? timeout }) : super(timeout: timeout);
|
||||||
|
|
||||||
/// Deserializes this command from the value generated by [serialize].
|
/// Deserializes this command from the value generated by [serialize].
|
||||||
SetTextEntryEmulation.deserialize(Map<String, String> json)
|
SetTextEntryEmulation.deserialize(Map<String, String> json)
|
||||||
|
@ -11,7 +11,7 @@ class WaitForCondition extends Command {
|
|||||||
/// Creates a command that waits for the given [condition] is met.
|
/// Creates a command that waits for the given [condition] is met.
|
||||||
///
|
///
|
||||||
/// The [condition] argument must not be null.
|
/// The [condition] argument must not be null.
|
||||||
const WaitForCondition(this.condition, {Duration timeout})
|
const WaitForCondition(this.condition, {Duration? timeout})
|
||||||
: assert(condition != null),
|
: assert(condition != null),
|
||||||
super(timeout: timeout);
|
super(timeout: timeout);
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ class WaitForCondition extends Command {
|
|||||||
)
|
)
|
||||||
class WaitUntilNoTransientCallbacks extends Command {
|
class WaitUntilNoTransientCallbacks extends Command {
|
||||||
/// Creates a command that waits for there to be no transient callbacks.
|
/// Creates a command that waits for there to be no transient callbacks.
|
||||||
const WaitUntilNoTransientCallbacks({ Duration timeout }) : super(timeout: timeout);
|
const WaitUntilNoTransientCallbacks({ Duration? timeout }) : super(timeout: timeout);
|
||||||
|
|
||||||
/// Deserializes this command from the value generated by [serialize].
|
/// Deserializes this command from the value generated by [serialize].
|
||||||
WaitUntilNoTransientCallbacks.deserialize(Map<String, String> json)
|
WaitUntilNoTransientCallbacks.deserialize(Map<String, String> json)
|
||||||
@ -76,7 +76,7 @@ class WaitUntilNoTransientCallbacks extends Command {
|
|||||||
)
|
)
|
||||||
class WaitUntilNoPendingFrame extends Command {
|
class WaitUntilNoPendingFrame extends Command {
|
||||||
/// Creates a command that waits until there's no pending frame scheduled.
|
/// Creates a command that waits until there's no pending frame scheduled.
|
||||||
const WaitUntilNoPendingFrame({ Duration timeout }) : super(timeout: timeout);
|
const WaitUntilNoPendingFrame({ Duration? timeout }) : super(timeout: timeout);
|
||||||
|
|
||||||
/// Deserializes this command from the value generated by [serialize].
|
/// Deserializes this command from the value generated by [serialize].
|
||||||
WaitUntilNoPendingFrame.deserialize(Map<String, String> json)
|
WaitUntilNoPendingFrame.deserialize(Map<String, String> json)
|
||||||
@ -108,7 +108,7 @@ class WaitUntilNoPendingFrame extends Command {
|
|||||||
)
|
)
|
||||||
class WaitUntilFirstFrameRasterized extends Command {
|
class WaitUntilFirstFrameRasterized extends Command {
|
||||||
/// Creates this command.
|
/// Creates this command.
|
||||||
const WaitUntilFirstFrameRasterized({ Duration timeout }) : super(timeout: timeout);
|
const WaitUntilFirstFrameRasterized({ Duration? timeout }) : super(timeout: timeout);
|
||||||
|
|
||||||
/// Deserializes this command from the value generated by [serialize].
|
/// Deserializes this command from the value generated by [serialize].
|
||||||
WaitUntilFirstFrameRasterized.deserialize(Map<String, String> json)
|
WaitUntilFirstFrameRasterized.deserialize(Map<String, String> json)
|
||||||
@ -124,7 +124,7 @@ class SerializationException implements Exception {
|
|||||||
const SerializationException([this.message]);
|
const SerializationException([this.message]);
|
||||||
|
|
||||||
/// The error message, possibly null.
|
/// The error message, possibly null.
|
||||||
final String message;
|
final String? message;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'SerializationException($message)';
|
String toString() => 'SerializationException($message)';
|
||||||
@ -271,7 +271,7 @@ class CombinedCondition extends SerializableWaitCondition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final List<SerializableWaitCondition> conditions = <SerializableWaitCondition>[];
|
final List<SerializableWaitCondition> conditions = <SerializableWaitCondition>[];
|
||||||
for (final Map<String, dynamic> condition in (json.decode(jsonMap['conditions']) as List<dynamic>).cast<Map<String, dynamic>>()) {
|
for (final Map<String, dynamic> condition in (json.decode(jsonMap['conditions']!) as List<dynamic>).cast<Map<String, dynamic>>()) {
|
||||||
conditions.add(_deserialize(condition.cast<String, String>()));
|
conditions.add(_deserialize(condition.cast<String, String>()));
|
||||||
}
|
}
|
||||||
return CombinedCondition(conditions);
|
return CombinedCondition(conditions);
|
||||||
@ -301,7 +301,7 @@ class CombinedCondition extends SerializableWaitCondition {
|
|||||||
/// The [json] argument must not be null.
|
/// The [json] argument must not be null.
|
||||||
SerializableWaitCondition _deserialize(Map<String, String> json) {
|
SerializableWaitCondition _deserialize(Map<String, String> json) {
|
||||||
assert(json != null);
|
assert(json != null);
|
||||||
final String conditionName = json['conditionName'];
|
final String conditionName = json['conditionName']!;
|
||||||
switch (conditionName) {
|
switch (conditionName) {
|
||||||
case 'NoTransientCallbacksCondition':
|
case 'NoTransientCallbacksCondition':
|
||||||
return NoTransientCallbacks.deserialize(json);
|
return NoTransientCallbacks.deserialize(json);
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// @dart = 2.8
|
||||||
|
|
||||||
import 'dart:io' show Platform;
|
import 'dart:io' show Platform;
|
||||||
|
|
||||||
import 'package:file/file.dart';
|
import 'package:file/file.dart';
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// @dart = 2.8
|
||||||
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:json_rpc_2/json_rpc_2.dart' as rpc;
|
import 'package:json_rpc_2/json_rpc_2.dart' as rpc;
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// @dart = 2.8
|
||||||
|
|
||||||
/// Returns the [p]-th percentile element from the [doubles].
|
/// Returns the [p]-th percentile element from the [doubles].
|
||||||
/// `List<doubles>` will be sorted.
|
/// `List<doubles>` will be sorted.
|
||||||
double findPercentile(List<double> doubles, double p) {
|
double findPercentile(List<double> doubles, double p) {
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// @dart = 2.8
|
||||||
|
|
||||||
import 'percentile_utils.dart';
|
import 'percentile_utils.dart';
|
||||||
import 'timeline.dart';
|
import 'timeline.dart';
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// @dart = 2.8
|
||||||
|
|
||||||
import 'percentile_utils.dart';
|
import 'percentile_utils.dart';
|
||||||
import 'timeline.dart';
|
import 'timeline.dart';
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// @dart = 2.8
|
||||||
|
|
||||||
/// Timeline data recorded by the Flutter runtime.
|
/// Timeline data recorded by the Flutter runtime.
|
||||||
class Timeline {
|
class Timeline {
|
||||||
/// Creates a timeline given JSON-encoded timeline data.
|
/// Creates a timeline given JSON-encoded timeline data.
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// @dart = 2.8
|
||||||
|
|
||||||
import 'dart:convert' show json, JsonEncoder;
|
import 'dart:convert' show json, JsonEncoder;
|
||||||
import 'dart:math' as math;
|
import 'dart:math' as math;
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// @dart = 2.8
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
@ -12,13 +14,12 @@ import 'package:json_rpc_2/json_rpc_2.dart' as rpc;
|
|||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
import 'package:vm_service_client/vm_service_client.dart';
|
import 'package:vm_service_client/vm_service_client.dart';
|
||||||
import 'package:webdriver/async_io.dart' as async_io;
|
|
||||||
import 'package:web_socket_channel/io.dart';
|
import 'package:web_socket_channel/io.dart';
|
||||||
|
import 'package:webdriver/async_io.dart' as async_io;
|
||||||
|
|
||||||
import '../../flutter_driver.dart';
|
import '../../flutter_driver.dart';
|
||||||
import '../common/error.dart';
|
import '../common/error.dart';
|
||||||
import '../common/frame_sync.dart';
|
import '../common/frame_sync.dart';
|
||||||
import '../common/fuchsia_compat.dart';
|
|
||||||
import '../common/health.dart';
|
import '../common/health.dart';
|
||||||
import '../common/message.dart';
|
import '../common/message.dart';
|
||||||
import 'common.dart';
|
import 'common.dart';
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// @dart = 2.8
|
||||||
|
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
@ -40,19 +40,19 @@ const String _extensionMethod = 'ext.flutter.$_extensionMethodName';
|
|||||||
///
|
///
|
||||||
/// Messages are described in string form and should return a [Future] which
|
/// Messages are described in string form and should return a [Future] which
|
||||||
/// eventually completes to a string response.
|
/// eventually completes to a string response.
|
||||||
typedef DataHandler = Future<String> Function(String message);
|
typedef DataHandler = Future<String> Function(String? message);
|
||||||
|
|
||||||
class _DriverBinding extends BindingBase with SchedulerBinding, ServicesBinding, GestureBinding, PaintingBinding, SemanticsBinding, RendererBinding, WidgetsBinding {
|
class _DriverBinding extends BindingBase with SchedulerBinding, ServicesBinding, GestureBinding, PaintingBinding, SemanticsBinding, RendererBinding, WidgetsBinding {
|
||||||
_DriverBinding(this._handler, this._silenceErrors, this.finders);
|
_DriverBinding(this._handler, this._silenceErrors, this.finders);
|
||||||
|
|
||||||
final DataHandler _handler;
|
final DataHandler? _handler;
|
||||||
final bool _silenceErrors;
|
final bool _silenceErrors;
|
||||||
final List<FinderExtension> finders;
|
final List<FinderExtension>? finders;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initServiceExtensions() {
|
void initServiceExtensions() {
|
||||||
super.initServiceExtensions();
|
super.initServiceExtensions();
|
||||||
final FlutterDriverExtension extension = FlutterDriverExtension(_handler, _silenceErrors, finders: finders);
|
final FlutterDriverExtension extension = FlutterDriverExtension(_handler, _silenceErrors, finders: finders ?? const <FinderExtension>[]);
|
||||||
registerServiceExtension(
|
registerServiceExtension(
|
||||||
name: _extensionMethodName,
|
name: _extensionMethodName,
|
||||||
callback: extension.call,
|
callback: extension.call,
|
||||||
@ -137,14 +137,14 @@ class _DriverBinding extends BindingBase with SchedulerBinding, ServicesBinding,
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
void enableFlutterDriverExtension({ DataHandler handler, bool silenceErrors = false, List<FinderExtension> finders}) {
|
void enableFlutterDriverExtension({ DataHandler? handler, bool silenceErrors = false, List<FinderExtension>? finders}) {
|
||||||
assert(WidgetsBinding.instance == null);
|
assert(WidgetsBinding.instance == null);
|
||||||
_DriverBinding(handler, silenceErrors, finders ?? <FinderExtension>[]);
|
_DriverBinding(handler, silenceErrors, finders ?? <FinderExtension>[]);
|
||||||
assert(WidgetsBinding.instance is _DriverBinding);
|
assert(WidgetsBinding.instance is _DriverBinding);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Signature for functions that handle a command and return a result.
|
/// Signature for functions that handle a command and return a result.
|
||||||
typedef CommandHandlerCallback = Future<Result> Function(Command c);
|
typedef CommandHandlerCallback = Future<Result?> Function(Command c);
|
||||||
|
|
||||||
/// Signature for functions that deserialize a JSON map to a command object.
|
/// Signature for functions that deserialize a JSON map to a command object.
|
||||||
typedef CommandDeserializerCallback = Command Function(Map<String, String> params);
|
typedef CommandDeserializerCallback = Command Function(Map<String, String> params);
|
||||||
@ -233,14 +233,14 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
|||||||
|
|
||||||
final TestTextInput _testTextInput = TestTextInput();
|
final TestTextInput _testTextInput = TestTextInput();
|
||||||
|
|
||||||
final DataHandler _requestDataHandler;
|
final DataHandler? _requestDataHandler;
|
||||||
final bool _silenceErrors;
|
final bool _silenceErrors;
|
||||||
|
|
||||||
void _log(String message) {
|
void _log(String message) {
|
||||||
driverLog('FlutterDriverExtension', message);
|
driverLog('FlutterDriverExtension', message);
|
||||||
}
|
}
|
||||||
|
|
||||||
final WidgetController _prober = LiveWidgetController(WidgetsBinding.instance);
|
final WidgetController _prober = LiveWidgetController(WidgetsBinding.instance!);
|
||||||
final Map<String, CommandHandlerCallback> _commandHandlers = <String, CommandHandlerCallback>{};
|
final Map<String, CommandHandlerCallback> _commandHandlers = <String, CommandHandlerCallback>{};
|
||||||
final Map<String, CommandDeserializerCallback> _commandDeserializers = <String, CommandDeserializerCallback>{};
|
final Map<String, CommandDeserializerCallback> _commandDeserializers = <String, CommandDeserializerCallback>{};
|
||||||
final Map<String, FinderExtension> _finderExtensions = <String, FinderExtension>{};
|
final Map<String, FinderExtension> _finderExtensions = <String, FinderExtension>{};
|
||||||
@ -261,20 +261,20 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
|||||||
/// the result into a subclass of [Result], but that's not strictly required.
|
/// the result into a subclass of [Result], but that's not strictly required.
|
||||||
@visibleForTesting
|
@visibleForTesting
|
||||||
Future<Map<String, dynamic>> call(Map<String, String> params) async {
|
Future<Map<String, dynamic>> call(Map<String, String> params) async {
|
||||||
final String commandKind = params['command'];
|
final String commandKind = params['command']!;
|
||||||
try {
|
try {
|
||||||
final CommandHandlerCallback commandHandler = _commandHandlers[commandKind];
|
final CommandHandlerCallback commandHandler = _commandHandlers[commandKind]!;
|
||||||
final CommandDeserializerCallback commandDeserializer =
|
final CommandDeserializerCallback commandDeserializer =
|
||||||
_commandDeserializers[commandKind];
|
_commandDeserializers[commandKind]!;
|
||||||
if (commandHandler == null || commandDeserializer == null)
|
if (commandHandler == null || commandDeserializer == null)
|
||||||
throw 'Extension $_extensionMethod does not support command $commandKind';
|
throw 'Extension $_extensionMethod does not support command $commandKind';
|
||||||
final Command command = commandDeserializer(params);
|
final Command command = commandDeserializer(params);
|
||||||
assert(WidgetsBinding.instance.isRootWidgetAttached || !command.requiresRootWidgetAttached,
|
assert(WidgetsBinding.instance!.isRootWidgetAttached || !command.requiresRootWidgetAttached,
|
||||||
'No root widget is attached; have you remembered to call runApp()?');
|
'No root widget is attached; have you remembered to call runApp()?');
|
||||||
Future<Result> responseFuture = commandHandler(command);
|
Future<Result?> responseFuture = commandHandler(command);
|
||||||
if (command.timeout != null)
|
if (command.timeout != null)
|
||||||
responseFuture = responseFuture.timeout(command.timeout);
|
responseFuture = responseFuture.timeout(command.timeout ?? Duration.zero);
|
||||||
final Result response = await responseFuture;
|
final Result? response = await responseFuture;
|
||||||
return _makeResponse(response?.toJson());
|
return _makeResponse(response?.toJson());
|
||||||
} on TimeoutException catch (error, stackTrace) {
|
} on TimeoutException catch (error, stackTrace) {
|
||||||
final String message = 'Timeout while executing $commandKind: $error\n$stackTrace';
|
final String message = 'Timeout while executing $commandKind: $error\n$stackTrace';
|
||||||
@ -298,11 +298,11 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
|||||||
Future<Health> _getHealth(Command command) async => const Health(HealthStatus.ok);
|
Future<Health> _getHealth(Command command) async => const Health(HealthStatus.ok);
|
||||||
|
|
||||||
Future<LayerTree> _getLayerTree(Command command) async {
|
Future<LayerTree> _getLayerTree(Command command) async {
|
||||||
return LayerTree(RendererBinding.instance?.renderView?.debugLayer?.toStringDeep());
|
return LayerTree(RendererBinding.instance?.renderView.debugLayer?.toStringDeep());
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<RenderTree> _getRenderTree(Command command) async {
|
Future<RenderTree> _getRenderTree(Command command) async {
|
||||||
return RenderTree(RendererBinding.instance?.renderView?.toStringDeep());
|
return RenderTree(RendererBinding.instance?.renderView.toStringDeep());
|
||||||
}
|
}
|
||||||
|
|
||||||
// This can be used to wait for the first frame being rasterized during app launch.
|
// This can be used to wait for the first frame being rasterized during app launch.
|
||||||
@ -310,16 +310,16 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
|||||||
'This method has been deprecated in favor of _waitForCondition. '
|
'This method has been deprecated in favor of _waitForCondition. '
|
||||||
'This feature was deprecated after v1.9.3.'
|
'This feature was deprecated after v1.9.3.'
|
||||||
)
|
)
|
||||||
Future<Result> _waitUntilFirstFrameRasterized(Command command) async {
|
Future<Result?> _waitUntilFirstFrameRasterized(Command command) async {
|
||||||
await WidgetsBinding.instance.waitUntilFirstFrameRasterized;
|
await WidgetsBinding.instance!.waitUntilFirstFrameRasterized;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Waits until at the end of a frame the provided [condition] is [true].
|
// Waits until at the end of a frame the provided [condition] is [true].
|
||||||
Future<void> _waitUntilFrame(bool condition(), [ Completer<void> completer ]) {
|
Future<void> _waitUntilFrame(bool condition(), [ Completer<void>? completer ]) {
|
||||||
completer ??= Completer<void>();
|
completer ??= Completer<void>();
|
||||||
if (!condition()) {
|
if (!condition()) {
|
||||||
SchedulerBinding.instance.addPostFrameCallback((Duration timestamp) {
|
SchedulerBinding.instance!.addPostFrameCallback((Duration timestamp) {
|
||||||
_waitUntilFrame(condition, completer);
|
_waitUntilFrame(condition, completer);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -331,12 +331,12 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
|||||||
/// Runs `finder` repeatedly until it finds one or more [Element]s.
|
/// Runs `finder` repeatedly until it finds one or more [Element]s.
|
||||||
Future<Finder> _waitForElement(Finder finder) async {
|
Future<Finder> _waitForElement(Finder finder) async {
|
||||||
if (_frameSync)
|
if (_frameSync)
|
||||||
await _waitUntilFrame(() => SchedulerBinding.instance.transientCallbackCount == 0);
|
await _waitUntilFrame(() => SchedulerBinding.instance!.transientCallbackCount == 0);
|
||||||
|
|
||||||
await _waitUntilFrame(() => finder.evaluate().isNotEmpty);
|
await _waitUntilFrame(() => finder.evaluate().isNotEmpty);
|
||||||
|
|
||||||
if (_frameSync)
|
if (_frameSync)
|
||||||
await _waitUntilFrame(() => SchedulerBinding.instance.transientCallbackCount == 0);
|
await _waitUntilFrame(() => SchedulerBinding.instance!.transientCallbackCount == 0);
|
||||||
|
|
||||||
return finder;
|
return finder;
|
||||||
}
|
}
|
||||||
@ -344,12 +344,12 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
|||||||
/// Runs `finder` repeatedly until it finds zero [Element]s.
|
/// Runs `finder` repeatedly until it finds zero [Element]s.
|
||||||
Future<Finder> _waitForAbsentElement(Finder finder) async {
|
Future<Finder> _waitForAbsentElement(Finder finder) async {
|
||||||
if (_frameSync)
|
if (_frameSync)
|
||||||
await _waitUntilFrame(() => SchedulerBinding.instance.transientCallbackCount == 0);
|
await _waitUntilFrame(() => SchedulerBinding.instance!.transientCallbackCount == 0);
|
||||||
|
|
||||||
await _waitUntilFrame(() => finder.evaluate().isEmpty);
|
await _waitUntilFrame(() => finder.evaluate().isEmpty);
|
||||||
|
|
||||||
if (_frameSync)
|
if (_frameSync)
|
||||||
await _waitUntilFrame(() => SchedulerBinding.instance.transientCallbackCount == 0);
|
await _waitUntilFrame(() => SchedulerBinding.instance!.transientCallbackCount == 0);
|
||||||
|
|
||||||
return finder;
|
return finder;
|
||||||
}
|
}
|
||||||
@ -372,7 +372,7 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
|||||||
if (element is! RenderObjectElement) {
|
if (element is! RenderObjectElement) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final String semanticsLabel = element.renderObject?.debugSemantics?.label;
|
final String? semanticsLabel = element.renderObject.debugSemantics?.label;
|
||||||
if (semanticsLabel == null) {
|
if (semanticsLabel == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -449,7 +449,7 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
|||||||
return _createDescendantFinder(finder as Descendant);
|
return _createDescendantFinder(finder as Descendant);
|
||||||
default:
|
default:
|
||||||
if (_finderExtensions.containsKey(finder.finderType)) {
|
if (_finderExtensions.containsKey(finder.finderType)) {
|
||||||
return _finderExtensions[finder.finderType].createFinder(finder);
|
return _finderExtensions[finder.finderType]!.createFinder(finder);
|
||||||
} else {
|
} else {
|
||||||
throw 'Unsupported finder type: ${finder.finderType}';
|
throw 'Unsupported finder type: ${finder.finderType}';
|
||||||
}
|
}
|
||||||
@ -477,7 +477,7 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
|||||||
return const WaitForAbsentResult();
|
return const WaitForAbsentResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Result> _waitForCondition(Command command) async {
|
Future<Result?> _waitForCondition(Command command) async {
|
||||||
assert(command != null);
|
assert(command != null);
|
||||||
final WaitForCondition waitForConditionCommand = command as WaitForCondition;
|
final WaitForCondition waitForConditionCommand = command as WaitForCondition;
|
||||||
final WaitCondition condition = deserializeCondition(waitForConditionCommand.condition);
|
final WaitCondition condition = deserializeCondition(waitForConditionCommand.condition);
|
||||||
@ -489,9 +489,9 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
|||||||
'This method has been deprecated in favor of _waitForCondition. '
|
'This method has been deprecated in favor of _waitForCondition. '
|
||||||
'This feature was deprecated after v1.9.3.'
|
'This feature was deprecated after v1.9.3.'
|
||||||
)
|
)
|
||||||
Future<Result> _waitUntilNoTransientCallbacks(Command command) async {
|
Future<Result?> _waitUntilNoTransientCallbacks(Command command) async {
|
||||||
if (SchedulerBinding.instance.transientCallbackCount != 0)
|
if (SchedulerBinding.instance!.transientCallbackCount != 0)
|
||||||
await _waitUntilFrame(() => SchedulerBinding.instance.transientCallbackCount == 0);
|
await _waitUntilFrame(() => SchedulerBinding.instance!.transientCallbackCount == 0);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -518,10 +518,10 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
|||||||
'This method has been deprecated in favor of _waitForCondition. '
|
'This method has been deprecated in favor of _waitForCondition. '
|
||||||
'This feature was deprecated after v1.9.3.'
|
'This feature was deprecated after v1.9.3.'
|
||||||
)
|
)
|
||||||
Future<Result> _waitUntilNoPendingFrame(Command command) async {
|
Future<Result?> _waitUntilNoPendingFrame(Command command) async {
|
||||||
await _waitUntilFrame(() {
|
await _waitUntilFrame(() {
|
||||||
return SchedulerBinding.instance.transientCallbackCount == 0
|
return SchedulerBinding.instance!.transientCallbackCount == 0
|
||||||
&& !SchedulerBinding.instance.hasScheduledFrame;
|
&& !SchedulerBinding.instance!.hasScheduledFrame;
|
||||||
});
|
});
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -534,11 +534,11 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
|||||||
throw StateError('Found more than one element with the same ID: $elements');
|
throw StateError('Found more than one element with the same ID: $elements');
|
||||||
}
|
}
|
||||||
final Element element = elements.single;
|
final Element element = elements.single;
|
||||||
RenderObject renderObject = element.renderObject;
|
RenderObject? renderObject = element.renderObject;
|
||||||
SemanticsNode node;
|
SemanticsNode? node;
|
||||||
while (renderObject != null && node == null) {
|
while (renderObject != null && node == null) {
|
||||||
node = renderObject.debugSemantics;
|
node = renderObject.debugSemantics;
|
||||||
renderObject = renderObject.parent as RenderObject;
|
renderObject = renderObject.parent as RenderObject?;
|
||||||
}
|
}
|
||||||
if (node == null)
|
if (node == null)
|
||||||
throw StateError('No semantics data found');
|
throw StateError('No semantics data found');
|
||||||
@ -549,7 +549,7 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
|||||||
final GetOffset getOffsetCommand = command as GetOffset;
|
final GetOffset getOffsetCommand = command as GetOffset;
|
||||||
final Finder finder = await _waitForElement(_createFinder(getOffsetCommand.finder));
|
final Finder finder = await _waitForElement(_createFinder(getOffsetCommand.finder));
|
||||||
final Element element = finder.evaluate().single;
|
final Element element = finder.evaluate().single;
|
||||||
final RenderBox box = element.renderObject as RenderBox;
|
final RenderBox box = (element.renderObject as RenderBox?)!;
|
||||||
Offset localPoint;
|
Offset localPoint;
|
||||||
switch (getOffsetCommand.offsetType) {
|
switch (getOffsetCommand.offsetType) {
|
||||||
case OffsetType.topLeft:
|
case OffsetType.topLeft:
|
||||||
@ -579,7 +579,7 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
|||||||
DiagnosticsNode diagnosticsNode;
|
DiagnosticsNode diagnosticsNode;
|
||||||
switch (diagnosticsCommand.diagnosticsType) {
|
switch (diagnosticsCommand.diagnosticsType) {
|
||||||
case DiagnosticsType.renderObject:
|
case DiagnosticsType.renderObject:
|
||||||
diagnosticsNode = element.renderObject.toDiagnosticsNode();
|
diagnosticsNode = element.renderObject!.toDiagnosticsNode();
|
||||||
break;
|
break;
|
||||||
case DiagnosticsType.widget:
|
case DiagnosticsType.widget:
|
||||||
diagnosticsNode = element.toDiagnosticsNode();
|
diagnosticsNode = element.toDiagnosticsNode();
|
||||||
@ -615,7 +615,11 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
|||||||
Future<ScrollResult> _scrollIntoView(Command command) async {
|
Future<ScrollResult> _scrollIntoView(Command command) async {
|
||||||
final ScrollIntoView scrollIntoViewCommand = command as ScrollIntoView;
|
final ScrollIntoView scrollIntoViewCommand = command as ScrollIntoView;
|
||||||
final Finder target = await _waitForElement(_createFinder(scrollIntoViewCommand.finder));
|
final Finder target = await _waitForElement(_createFinder(scrollIntoViewCommand.finder));
|
||||||
await Scrollable.ensureVisible(target.evaluate().single, duration: const Duration(milliseconds: 100), alignment: scrollIntoViewCommand.alignment ?? 0.0);
|
await Scrollable.ensureVisible(
|
||||||
|
target.evaluate().single,
|
||||||
|
duration: const Duration(milliseconds: 100),
|
||||||
|
alignment: scrollIntoViewCommand.alignment,
|
||||||
|
);
|
||||||
return const ScrollResult();
|
return const ScrollResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -624,7 +628,7 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
|||||||
final Finder target = await _waitForElement(_createFinder(getTextCommand.finder));
|
final Finder target = await _waitForElement(_createFinder(getTextCommand.finder));
|
||||||
|
|
||||||
final Widget widget = target.evaluate().single.widget;
|
final Widget widget = target.evaluate().single.widget;
|
||||||
String text;
|
String? text;
|
||||||
|
|
||||||
if (widget.runtimeType == Text) {
|
if (widget.runtimeType == Text) {
|
||||||
text = (widget as Text).data;
|
text = (widget as Text).data;
|
||||||
@ -634,9 +638,9 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
|||||||
text = (richText.text as TextSpan).text;
|
text = (richText.text as TextSpan).text;
|
||||||
}
|
}
|
||||||
} else if (widget.runtimeType == TextField) {
|
} else if (widget.runtimeType == TextField) {
|
||||||
text = (widget as TextField).controller.text;
|
text = (widget as TextField).controller?.text;
|
||||||
} else if (widget.runtimeType == TextFormField) {
|
} else if (widget.runtimeType == TextFormField) {
|
||||||
text = (widget as TextFormField).controller.text;
|
text = (widget as TextFormField).controller?.text;
|
||||||
} else if (widget.runtimeType == EditableText) {
|
} else if (widget.runtimeType == EditableText) {
|
||||||
text = (widget as EditableText).controller.text;
|
text = (widget as EditableText).controller.text;
|
||||||
}
|
}
|
||||||
@ -670,7 +674,9 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
|||||||
|
|
||||||
Future<RequestDataResult> _requestData(Command command) async {
|
Future<RequestDataResult> _requestData(Command command) async {
|
||||||
final RequestData requestDataCommand = command as RequestData;
|
final RequestData requestDataCommand = command as RequestData;
|
||||||
return RequestDataResult(_requestDataHandler == null ? 'No requestData Extension registered' : await _requestDataHandler(requestDataCommand.message));
|
return RequestDataResult(_requestDataHandler == null
|
||||||
|
? 'No requestData Extension registered'
|
||||||
|
: await _requestDataHandler!(requestDataCommand.message));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<SetFrameSyncResult> _setFrameSync(Command command) async {
|
Future<SetFrameSyncResult> _setFrameSync(Command command) async {
|
||||||
@ -679,24 +685,24 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
|||||||
return const SetFrameSyncResult();
|
return const SetFrameSyncResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
SemanticsHandle _semantics;
|
SemanticsHandle? _semantics;
|
||||||
bool get _semanticsIsEnabled => RendererBinding.instance.pipelineOwner.semanticsOwner != null;
|
bool get _semanticsIsEnabled => RendererBinding.instance!.pipelineOwner.semanticsOwner != null;
|
||||||
|
|
||||||
Future<SetSemanticsResult> _setSemantics(Command command) async {
|
Future<SetSemanticsResult> _setSemantics(Command command) async {
|
||||||
final SetSemantics setSemanticsCommand = command as SetSemantics;
|
final SetSemantics setSemanticsCommand = command as SetSemantics;
|
||||||
final bool semanticsWasEnabled = _semanticsIsEnabled;
|
final bool semanticsWasEnabled = _semanticsIsEnabled;
|
||||||
if (setSemanticsCommand.enabled && _semantics == null) {
|
if (setSemanticsCommand.enabled && _semantics == null) {
|
||||||
_semantics = RendererBinding.instance.pipelineOwner.ensureSemantics();
|
_semantics = RendererBinding.instance!.pipelineOwner.ensureSemantics();
|
||||||
if (!semanticsWasEnabled) {
|
if (!semanticsWasEnabled) {
|
||||||
// wait for the first frame where semantics is enabled.
|
// wait for the first frame where semantics is enabled.
|
||||||
final Completer<void> completer = Completer<void>();
|
final Completer<void> completer = Completer<void>();
|
||||||
SchedulerBinding.instance.addPostFrameCallback((Duration d) {
|
SchedulerBinding.instance!.addPostFrameCallback((Duration d) {
|
||||||
completer.complete();
|
completer.complete();
|
||||||
});
|
});
|
||||||
await completer.future;
|
await completer.future;
|
||||||
}
|
}
|
||||||
} else if (!setSemanticsCommand.enabled && _semantics != null) {
|
} else if (!setSemanticsCommand.enabled && _semantics != null) {
|
||||||
_semantics.dispose();
|
_semantics!.dispose();
|
||||||
_semantics = null;
|
_semantics = null;
|
||||||
}
|
}
|
||||||
return SetSemanticsResult(semanticsWasEnabled != _semanticsIsEnabled);
|
return SetSemanticsResult(semanticsWasEnabled != _semanticsIsEnabled);
|
||||||
|
@ -49,12 +49,12 @@ class _InternalNoTransientCallbacksCondition implements WaitCondition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool get condition => SchedulerBinding.instance.transientCallbackCount == 0;
|
bool get condition => SchedulerBinding.instance!.transientCallbackCount == 0;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> wait() async {
|
Future<void> wait() async {
|
||||||
while (!condition) {
|
while (!condition) {
|
||||||
await SchedulerBinding.instance.endOfFrame;
|
await SchedulerBinding.instance!.endOfFrame;
|
||||||
}
|
}
|
||||||
assert(condition);
|
assert(condition);
|
||||||
}
|
}
|
||||||
@ -77,12 +77,12 @@ class _InternalNoPendingFrameCondition implements WaitCondition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool get condition => !SchedulerBinding.instance.hasScheduledFrame;
|
bool get condition => !SchedulerBinding.instance!.hasScheduledFrame;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> wait() async {
|
Future<void> wait() async {
|
||||||
while (!condition) {
|
while (!condition) {
|
||||||
await SchedulerBinding.instance.endOfFrame;
|
await SchedulerBinding.instance!.endOfFrame;
|
||||||
}
|
}
|
||||||
assert(condition);
|
assert(condition);
|
||||||
}
|
}
|
||||||
@ -105,11 +105,11 @@ class _InternalFirstFrameRasterizedCondition implements WaitCondition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool get condition => WidgetsBinding.instance.firstFrameRasterized;
|
bool get condition => WidgetsBinding.instance!.firstFrameRasterized;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> wait() async {
|
Future<void> wait() async {
|
||||||
await WidgetsBinding.instance.waitUntilFirstFrameRasterized;
|
await WidgetsBinding.instance!.waitUntilFirstFrameRasterized;
|
||||||
assert(condition);
|
assert(condition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -132,13 +132,13 @@ class _InternalNoPendingPlatformMessagesCondition implements WaitCondition {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool get condition {
|
bool get condition {
|
||||||
final TestDefaultBinaryMessenger binaryMessenger = ServicesBinding.instance.defaultBinaryMessenger as TestDefaultBinaryMessenger;
|
final TestDefaultBinaryMessenger binaryMessenger = ServicesBinding.instance!.defaultBinaryMessenger as TestDefaultBinaryMessenger;
|
||||||
return binaryMessenger.pendingMessageCount == 0;
|
return binaryMessenger.pendingMessageCount == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> wait() async {
|
Future<void> wait() async {
|
||||||
final TestDefaultBinaryMessenger binaryMessenger = ServicesBinding.instance.defaultBinaryMessenger as TestDefaultBinaryMessenger;
|
final TestDefaultBinaryMessenger binaryMessenger = ServicesBinding.instance!.defaultBinaryMessenger as TestDefaultBinaryMessenger;
|
||||||
while (!condition) {
|
while (!condition) {
|
||||||
await binaryMessenger.platformMessagesFinished;
|
await binaryMessenger.platformMessagesFinished;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ author: Flutter Authors <flutter-dev@googlegroups.com>
|
|||||||
|
|
||||||
environment:
|
environment:
|
||||||
# The pub client defaults to an <2.0.0 sdk constraint which we need to explicitly overwrite.
|
# The pub client defaults to an <2.0.0 sdk constraint which we need to explicitly overwrite.
|
||||||
sdk: ">=2.2.2 <3.0.0"
|
sdk: ">=2.10.0-0.0.dev <3.0.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
file: 6.0.0-nullsafety.2
|
file: 6.0.0-nullsafety.2
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// @dart = 2.8
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/rendering.dart';
|
import 'package:flutter/rendering.dart';
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// @dart = 2.8
|
||||||
|
|
||||||
import 'package:flutter_driver/flutter_driver.dart';
|
import 'package:flutter_driver/flutter_driver.dart';
|
||||||
import 'package:flutter_driver/src/common/find.dart';
|
import 'package:flutter_driver/src/common/find.dart';
|
||||||
import 'package:mockito/mockito.dart';
|
import 'package:mockito/mockito.dart';
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// @dart = 2.8
|
||||||
|
|
||||||
import 'package:flutter_driver/src/extension/_extension_io.dart';
|
import 'package:flutter_driver/src/extension/_extension_io.dart';
|
||||||
|
|
||||||
import '../../common.dart';
|
import '../../common.dart';
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
// @dart = 2.8
|
||||||
|
|
||||||
|
import 'package:flutter_driver/flutter_driver.dart';
|
||||||
|
|
||||||
|
import '../../common.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
test('RequestData does not insert "null" string when no message is provided', () {
|
||||||
|
const RequestData data = RequestData(null);
|
||||||
|
|
||||||
|
expect(data.serialize(), <String, String>{'command': 'request_data'});
|
||||||
|
});
|
||||||
|
}
|
@ -2,6 +2,8 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// @dart = 2.8
|
||||||
|
|
||||||
import 'dart:convert' show json;
|
import 'dart:convert' show json;
|
||||||
|
|
||||||
import 'package:file/file.dart';
|
import 'package:file/file.dart';
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// @dart = 2.8
|
||||||
|
|
||||||
import 'package:flutter_driver/src/driver/timeline.dart';
|
import 'package:flutter_driver/src/driver/timeline.dart';
|
||||||
|
|
||||||
import '../../common.dart';
|
import '../../common.dart';
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// @dart = 2.8
|
||||||
|
|
||||||
import 'package:flutter_driver/src/common/wait.dart';
|
import 'package:flutter_driver/src/common/wait.dart';
|
||||||
|
|
||||||
import '../../common.dart';
|
import '../../common.dart';
|
||||||
|
@ -9,4 +9,4 @@ analyzer:
|
|||||||
always_require_non_null_named_parameters: false # not needed with nnbd
|
always_require_non_null_named_parameters: false # not needed with nnbd
|
||||||
unrelated_type_equality_checks: false # https://github.com/dart-lang/linter/issues/2196
|
unrelated_type_equality_checks: false # https://github.com/dart-lang/linter/issues/2196
|
||||||
void_checks: false # https://github.com/dart-lang/linter/issues/2185
|
void_checks: false # https://github.com/dart-lang/linter/issues/2185
|
||||||
unnecessary_null_comparison: false # https://github.com/dart-lang/language/issues/1018
|
unnecessary_null_comparison: false # Turned off until null-safe rollout is complete.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user