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
|
||||
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 # 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
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
/// Provides API to test Flutter applications that run on real
|
||||
/// devices and emulators.
|
||||
///
|
||||
|
@ -27,16 +27,16 @@ class GetDiagnosticsTree extends CommandWithTarget {
|
||||
GetDiagnosticsTree(SerializableFinder finder, this.diagnosticsType, {
|
||||
this.subtreeDepth = 0,
|
||||
this.includeProperties = true,
|
||||
Duration timeout,
|
||||
Duration? timeout,
|
||||
}) : assert(subtreeDepth != null),
|
||||
assert(includeProperties != null),
|
||||
super(finder, timeout: timeout);
|
||||
|
||||
/// Deserializes this command from the value generated by [serialize].
|
||||
GetDiagnosticsTree.deserialize(Map<String, String> json, DeserializeFinderFactory finderFactory)
|
||||
: subtreeDepth = int.parse(json['subtreeDepth']),
|
||||
: subtreeDepth = int.parse(json['subtreeDepth']!),
|
||||
includeProperties = json['includeProperties'] == 'true',
|
||||
diagnosticsType = _diagnosticsTypeIndex.lookupBySimpleName(json['diagnosticsType']),
|
||||
diagnosticsType = _diagnosticsTypeIndex.lookupBySimpleName(json['diagnosticsType']!),
|
||||
super.deserialize(json, finderFactory);
|
||||
|
||||
/// 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
|
||||
/// [GetDiagnosticsTree] command.
|
||||
final Map<String, Object> json;
|
||||
final Map<String, dynamic> json;
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() => json;
|
||||
|
@ -31,10 +31,10 @@ class EnumIndex<E> {
|
||||
final Map<E, String> _valueToName;
|
||||
|
||||
/// 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].
|
||||
String toSimpleName(E enumValue) => _valueToName[enumValue];
|
||||
String toSimpleName(E enumValue) => _valueToName[enumValue]!;
|
||||
}
|
||||
|
||||
String _getSimpleName(dynamic enumValue) {
|
||||
|
@ -13,7 +13,7 @@ import 'message.dart';
|
||||
mixin DeserializeFinderFactory {
|
||||
/// Deserializes the finder from JSON generated by [SerializableFinder.serialize].
|
||||
SerializableFinder deserializeFinder(Map<String, String> json) {
|
||||
final String finderType = json['finderType'];
|
||||
final String? finderType = json['finderType'];
|
||||
switch (finderType) {
|
||||
case 'ByType': return ByType.deserialize(json);
|
||||
case 'ByValueKey': return ByValueKey.deserialize(json);
|
||||
@ -41,7 +41,7 @@ DriverError _createInvalidKeyValueTypeError(String invalidType) {
|
||||
/// and add more keys to the returned map.
|
||||
abstract class CommandWithTarget extends Command {
|
||||
/// 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');
|
||||
}
|
||||
|
||||
@ -72,7 +72,7 @@ class WaitFor extends CommandWithTarget {
|
||||
/// appear within the [timeout] amount of time.
|
||||
///
|
||||
/// 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);
|
||||
|
||||
/// Deserializes this command from the value generated by [serialize].
|
||||
@ -102,7 +102,7 @@ class WaitForAbsent extends CommandWithTarget {
|
||||
/// disappear within the [timeout] amount of time.
|
||||
///
|
||||
/// 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);
|
||||
|
||||
/// 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].
|
||||
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].
|
||||
static BySemanticsLabel deserialize(Map<String, String> json) {
|
||||
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].
|
||||
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].
|
||||
static ByValueKey deserialize(Map<String, String> json) {
|
||||
final String keyValueString = json['keyValueString'];
|
||||
final String keyValueType = json['keyValueType'];
|
||||
final String keyValueString = json['keyValueString']!;
|
||||
final String keyValueType = json['keyValueType']!;
|
||||
switch (keyValueType) {
|
||||
case 'int':
|
||||
return ByValueKey(int.parse(keyValueString));
|
||||
@ -292,7 +292,7 @@ class ByType extends SerializableFinder {
|
||||
|
||||
/// Deserializes the finder from JSON generated by [serialize].
|
||||
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 {
|
||||
/// Creates a descendant finder.
|
||||
const Descendant({
|
||||
@required this.of,
|
||||
@required this.matching,
|
||||
required this.of,
|
||||
required this.matching,
|
||||
this.matchRoot = false,
|
||||
this.firstMatchOnly = false,
|
||||
});
|
||||
@ -353,9 +353,9 @@ class Descendant extends SerializableFinder {
|
||||
/// Deserializes the finder from JSON generated by [serialize].
|
||||
static Descendant deserialize(Map<String, String> json, DeserializeFinderFactory finderFactory) {
|
||||
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 =
|
||||
Map<String, String>.from(jsonDecode(json['matching']) as Map<String, dynamic>);
|
||||
Map<String, String>.from(jsonDecode(json['matching']!) as Map<String, dynamic>);
|
||||
return Descendant(
|
||||
of: finderFactory.deserializeFinder(jsonOfMatcher),
|
||||
matching: finderFactory.deserializeFinder(jsonMatchingMatcher),
|
||||
@ -373,8 +373,8 @@ class Descendant extends SerializableFinder {
|
||||
class Ancestor extends SerializableFinder {
|
||||
/// Creates an ancestor finder.
|
||||
const Ancestor({
|
||||
@required this.of,
|
||||
@required this.matching,
|
||||
required this.of,
|
||||
required this.matching,
|
||||
this.matchRoot = false,
|
||||
this.firstMatchOnly = false,
|
||||
});
|
||||
@ -408,9 +408,9 @@ class Ancestor extends SerializableFinder {
|
||||
/// Deserializes the finder from JSON generated by [serialize].
|
||||
static Ancestor deserialize(Map<String, String> json, DeserializeFinderFactory finderFactory) {
|
||||
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 =
|
||||
Map<String, String>.from(jsonDecode(json['matching']) as Map<String, dynamic>);
|
||||
Map<String, String>.from(jsonDecode(json['matching']!) as Map<String, dynamic>);
|
||||
return Ancestor(
|
||||
of: finderFactory.deserializeFinder(jsonOfMatcher),
|
||||
matching: finderFactory.deserializeFinder(jsonMatchingMatcher),
|
||||
@ -435,7 +435,7 @@ class Ancestor extends SerializableFinder {
|
||||
class GetSemanticsId extends CommandWithTarget {
|
||||
|
||||
/// 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.
|
||||
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.
|
||||
class SetFrameSync extends Command {
|
||||
/// 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].
|
||||
SetFrameSync.deserialize(Map<String, String> params)
|
||||
: enabled = params['enabled'].toLowerCase() == 'true',
|
||||
: enabled = params['enabled']!.toLowerCase() == 'true',
|
||||
super.deserialize(params);
|
||||
|
||||
/// 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
|
||||
// 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.
|
||||
import 'dart:core';
|
||||
import 'dart:io';
|
||||
|
||||
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].
|
||||
class GetOffset extends CommandWithTarget {
|
||||
/// 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].
|
||||
GetOffset.deserialize(Map<String, String> json, DeserializeFinderFactory finderFactory)
|
||||
: offsetType = _offsetTypeIndex.lookupBySimpleName(json['offsetType']),
|
||||
: offsetType = _offsetTypeIndex.lookupBySimpleName(json['offsetType']!),
|
||||
super.deserialize(json, finderFactory);
|
||||
|
||||
@override
|
||||
|
@ -8,7 +8,7 @@ import 'message.dart';
|
||||
/// A Flutter Driver command that taps on a target widget located by [finder].
|
||||
class Tap extends CommandWithTarget {
|
||||
/// 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].
|
||||
Tap.deserialize(Map<String, String> json, DeserializeFinderFactory finderFactory) : super.deserialize(json, finderFactory);
|
||||
@ -42,15 +42,15 @@ class Scroll extends CommandWithTarget {
|
||||
this.dy,
|
||||
this.duration,
|
||||
this.frequency, {
|
||||
Duration timeout,
|
||||
Duration? timeout,
|
||||
}) : super(finder, timeout: timeout);
|
||||
|
||||
/// Deserializes this command from the value generated by [serialize].
|
||||
Scroll.deserialize(Map<String, String> json, DeserializeFinderFactory finderFactory)
|
||||
: dx = double.parse(json['dx']),
|
||||
dy = double.parse(json['dy']),
|
||||
duration = Duration(microseconds: int.parse(json['duration'])),
|
||||
frequency = int.parse(json['frequency']),
|
||||
: dx = double.parse(json['dx']!),
|
||||
dy = double.parse(json['dy']!),
|
||||
duration = Duration(microseconds: int.parse(json['duration']!)),
|
||||
frequency = int.parse(json['frequency']!),
|
||||
super.deserialize(json, finderFactory);
|
||||
|
||||
/// Delta X offset per move event.
|
||||
@ -96,11 +96,11 @@ class ScrollResult extends Result {
|
||||
class ScrollIntoView extends CommandWithTarget {
|
||||
/// Creates this command given a [finder] used to locate the widget to be
|
||||
/// 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].
|
||||
ScrollIntoView.deserialize(Map<String, String> json, DeserializeFinderFactory finderFactory)
|
||||
: alignment = double.parse(json['alignment']),
|
||||
: alignment = double.parse(json['alignment']!),
|
||||
super.deserialize(json, finderFactory);
|
||||
|
||||
/// How the widget should be aligned.
|
||||
|
@ -8,7 +8,7 @@ import 'message.dart';
|
||||
/// A Flutter Driver command that requests an application health check.
|
||||
class GetHealth extends 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].
|
||||
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.
|
||||
class GetLayerTree extends Command {
|
||||
/// 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].
|
||||
GetLayerTree.deserialize(Map<String, String> json) : super.deserialize(json);
|
||||
@ -23,7 +23,7 @@ class LayerTree extends Result {
|
||||
const LayerTree(this.tree);
|
||||
|
||||
/// String representation of the layer tree.
|
||||
final String tree;
|
||||
final String? tree;
|
||||
|
||||
/// Deserializes the result from JSON.
|
||||
static LayerTree fromJson(Map<String, dynamic> json) {
|
||||
|
@ -15,8 +15,8 @@ abstract class Command {
|
||||
Command.deserialize(Map<String, String> json)
|
||||
: timeout = _parseTimeout(json);
|
||||
|
||||
static Duration _parseTimeout(Map<String, String> json) {
|
||||
final String timeout = json['timeout'];
|
||||
static Duration? _parseTimeout(Map<String, String> json) {
|
||||
final String? timeout = json['timeout'];
|
||||
if (timeout == null)
|
||||
return null;
|
||||
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
|
||||
/// long in test environments (e.g. because the test host is overloaded), and
|
||||
/// having timeouts essentially means having race conditions.
|
||||
final Duration timeout;
|
||||
final Duration? timeout;
|
||||
|
||||
/// Identifies the type of the command object and of the handler.
|
||||
String get kind;
|
||||
@ -53,7 +53,7 @@ abstract class Command {
|
||||
'command': kind,
|
||||
};
|
||||
if (timeout != null)
|
||||
result['timeout'] = '${timeout.inMilliseconds}';
|
||||
result['timeout'] = '${timeout!.inMilliseconds}';
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import 'message.dart';
|
||||
/// A Flutter Driver command that requests a string representation of the render tree.
|
||||
class GetRenderTree extends Command {
|
||||
/// 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].
|
||||
GetRenderTree.deserialize(Map<String, String> json) : super.deserialize(json);
|
||||
@ -23,7 +23,7 @@ class RenderTree extends Result {
|
||||
const RenderTree(this.tree);
|
||||
|
||||
/// String representation of the render tree.
|
||||
final String tree;
|
||||
final String? tree;
|
||||
|
||||
/// Deserializes the result from JSON.
|
||||
static RenderTree fromJson(Map<String, dynamic> json) {
|
||||
|
@ -8,7 +8,7 @@ import 'message.dart';
|
||||
/// string response.
|
||||
class RequestData extends Command {
|
||||
/// 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].
|
||||
RequestData.deserialize(Map<String, String> params)
|
||||
@ -16,7 +16,7 @@ class RequestData extends Command {
|
||||
super.deserialize(params);
|
||||
|
||||
/// The message being sent from the test to the application.
|
||||
final String message;
|
||||
final String? message;
|
||||
|
||||
@override
|
||||
String get kind => 'request_data';
|
||||
@ -26,7 +26,8 @@ class RequestData extends Command {
|
||||
|
||||
@override
|
||||
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.
|
||||
class SetSemantics extends Command {
|
||||
/// 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].
|
||||
SetSemantics.deserialize(Map<String, String> params)
|
||||
: enabled = params['enabled'].toLowerCase() == 'true',
|
||||
: enabled = params['enabled']!.toLowerCase() == 'true',
|
||||
super.deserialize(params);
|
||||
|
||||
/// 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.
|
||||
class GetText extends CommandWithTarget {
|
||||
/// [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].
|
||||
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.
|
||||
class EnterText extends Command {
|
||||
/// 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].
|
||||
EnterText.deserialize(Map<String, String> json)
|
||||
: text = json['text'],
|
||||
: text = json['text']!,
|
||||
super.deserialize(json);
|
||||
|
||||
/// 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.
|
||||
class SetTextEntryEmulation extends Command {
|
||||
/// 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].
|
||||
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.
|
||||
///
|
||||
/// The [condition] argument must not be null.
|
||||
const WaitForCondition(this.condition, {Duration timeout})
|
||||
const WaitForCondition(this.condition, {Duration? timeout})
|
||||
: assert(condition != null),
|
||||
super(timeout: timeout);
|
||||
|
||||
@ -51,7 +51,7 @@ class WaitForCondition extends Command {
|
||||
)
|
||||
class WaitUntilNoTransientCallbacks extends Command {
|
||||
/// 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].
|
||||
WaitUntilNoTransientCallbacks.deserialize(Map<String, String> json)
|
||||
@ -76,7 +76,7 @@ class WaitUntilNoTransientCallbacks extends Command {
|
||||
)
|
||||
class WaitUntilNoPendingFrame extends Command {
|
||||
/// 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].
|
||||
WaitUntilNoPendingFrame.deserialize(Map<String, String> json)
|
||||
@ -108,7 +108,7 @@ class WaitUntilNoPendingFrame extends Command {
|
||||
)
|
||||
class WaitUntilFirstFrameRasterized extends 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].
|
||||
WaitUntilFirstFrameRasterized.deserialize(Map<String, String> json)
|
||||
@ -124,7 +124,7 @@ class SerializationException implements Exception {
|
||||
const SerializationException([this.message]);
|
||||
|
||||
/// The error message, possibly null.
|
||||
final String message;
|
||||
final String? message;
|
||||
|
||||
@override
|
||||
String toString() => 'SerializationException($message)';
|
||||
@ -271,7 +271,7 @@ class CombinedCondition extends 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>()));
|
||||
}
|
||||
return CombinedCondition(conditions);
|
||||
@ -301,7 +301,7 @@ class CombinedCondition extends SerializableWaitCondition {
|
||||
/// The [json] argument must not be null.
|
||||
SerializableWaitCondition _deserialize(Map<String, String> json) {
|
||||
assert(json != null);
|
||||
final String conditionName = json['conditionName'];
|
||||
final String conditionName = json['conditionName']!;
|
||||
switch (conditionName) {
|
||||
case 'NoTransientCallbacksCondition':
|
||||
return NoTransientCallbacks.deserialize(json);
|
||||
|
@ -2,6 +2,8 @@
|
||||
// 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';
|
||||
|
@ -2,6 +2,8 @@
|
||||
// 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: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
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
/// Returns the [p]-th percentile element from the [doubles].
|
||||
/// `List<doubles>` will be sorted.
|
||||
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
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'percentile_utils.dart';
|
||||
import 'timeline.dart';
|
||||
|
||||
|
@ -2,6 +2,8 @@
|
||||
// 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';
|
||||
|
||||
|
@ -2,6 +2,8 @@
|
||||
// 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.
|
||||
|
@ -2,6 +2,8 @@
|
||||
// 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;
|
||||
|
||||
|
@ -2,6 +2,8 @@
|
||||
// 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';
|
||||
@ -12,13 +14,12 @@ import 'package:json_rpc_2/json_rpc_2.dart' as rpc;
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
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:webdriver/async_io.dart' as async_io;
|
||||
|
||||
import '../../flutter_driver.dart';
|
||||
import '../common/error.dart';
|
||||
import '../common/frame_sync.dart';
|
||||
import '../common/fuchsia_compat.dart';
|
||||
import '../common/health.dart';
|
||||
import '../common/message.dart';
|
||||
import 'common.dart';
|
||||
|
@ -2,6 +2,8 @@
|
||||
// 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';
|
||||
|
||||
|
@ -40,19 +40,19 @@ const String _extensionMethod = 'ext.flutter.$_extensionMethodName';
|
||||
///
|
||||
/// Messages are described in string form and should return a [Future] which
|
||||
/// 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 {
|
||||
_DriverBinding(this._handler, this._silenceErrors, this.finders);
|
||||
|
||||
final DataHandler _handler;
|
||||
final DataHandler? _handler;
|
||||
final bool _silenceErrors;
|
||||
final List<FinderExtension> finders;
|
||||
final List<FinderExtension>? finders;
|
||||
|
||||
@override
|
||||
void initServiceExtensions() {
|
||||
super.initServiceExtensions();
|
||||
final FlutterDriverExtension extension = FlutterDriverExtension(_handler, _silenceErrors, finders: finders);
|
||||
final FlutterDriverExtension extension = FlutterDriverExtension(_handler, _silenceErrors, finders: finders ?? const <FinderExtension>[]);
|
||||
registerServiceExtension(
|
||||
name: _extensionMethodName,
|
||||
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);
|
||||
_DriverBinding(handler, silenceErrors, finders ?? <FinderExtension>[]);
|
||||
assert(WidgetsBinding.instance is _DriverBinding);
|
||||
}
|
||||
|
||||
/// 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.
|
||||
typedef CommandDeserializerCallback = Command Function(Map<String, String> params);
|
||||
@ -233,14 +233,14 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
||||
|
||||
final TestTextInput _testTextInput = TestTextInput();
|
||||
|
||||
final DataHandler _requestDataHandler;
|
||||
final DataHandler? _requestDataHandler;
|
||||
final bool _silenceErrors;
|
||||
|
||||
void _log(String 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, CommandDeserializerCallback> _commandDeserializers = <String, CommandDeserializerCallback>{};
|
||||
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.
|
||||
@visibleForTesting
|
||||
Future<Map<String, dynamic>> call(Map<String, String> params) async {
|
||||
final String commandKind = params['command'];
|
||||
final String commandKind = params['command']!;
|
||||
try {
|
||||
final CommandHandlerCallback commandHandler = _commandHandlers[commandKind];
|
||||
final CommandHandlerCallback commandHandler = _commandHandlers[commandKind]!;
|
||||
final CommandDeserializerCallback commandDeserializer =
|
||||
_commandDeserializers[commandKind];
|
||||
_commandDeserializers[commandKind]!;
|
||||
if (commandHandler == null || commandDeserializer == null)
|
||||
throw 'Extension $_extensionMethod does not support command $commandKind';
|
||||
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()?');
|
||||
Future<Result> responseFuture = commandHandler(command);
|
||||
Future<Result?> responseFuture = commandHandler(command);
|
||||
if (command.timeout != null)
|
||||
responseFuture = responseFuture.timeout(command.timeout);
|
||||
final Result response = await responseFuture;
|
||||
responseFuture = responseFuture.timeout(command.timeout ?? Duration.zero);
|
||||
final Result? response = await responseFuture;
|
||||
return _makeResponse(response?.toJson());
|
||||
} on TimeoutException catch (error, 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<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 {
|
||||
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.
|
||||
@ -310,16 +310,16 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
||||
'This method has been deprecated in favor of _waitForCondition. '
|
||||
'This feature was deprecated after v1.9.3.'
|
||||
)
|
||||
Future<Result> _waitUntilFirstFrameRasterized(Command command) async {
|
||||
await WidgetsBinding.instance.waitUntilFirstFrameRasterized;
|
||||
Future<Result?> _waitUntilFirstFrameRasterized(Command command) async {
|
||||
await WidgetsBinding.instance!.waitUntilFirstFrameRasterized;
|
||||
return null;
|
||||
}
|
||||
|
||||
// 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>();
|
||||
if (!condition()) {
|
||||
SchedulerBinding.instance.addPostFrameCallback((Duration timestamp) {
|
||||
SchedulerBinding.instance!.addPostFrameCallback((Duration timestamp) {
|
||||
_waitUntilFrame(condition, completer);
|
||||
});
|
||||
} else {
|
||||
@ -331,12 +331,12 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
||||
/// Runs `finder` repeatedly until it finds one or more [Element]s.
|
||||
Future<Finder> _waitForElement(Finder finder) async {
|
||||
if (_frameSync)
|
||||
await _waitUntilFrame(() => SchedulerBinding.instance.transientCallbackCount == 0);
|
||||
await _waitUntilFrame(() => SchedulerBinding.instance!.transientCallbackCount == 0);
|
||||
|
||||
await _waitUntilFrame(() => finder.evaluate().isNotEmpty);
|
||||
|
||||
if (_frameSync)
|
||||
await _waitUntilFrame(() => SchedulerBinding.instance.transientCallbackCount == 0);
|
||||
await _waitUntilFrame(() => SchedulerBinding.instance!.transientCallbackCount == 0);
|
||||
|
||||
return finder;
|
||||
}
|
||||
@ -344,12 +344,12 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
||||
/// Runs `finder` repeatedly until it finds zero [Element]s.
|
||||
Future<Finder> _waitForAbsentElement(Finder finder) async {
|
||||
if (_frameSync)
|
||||
await _waitUntilFrame(() => SchedulerBinding.instance.transientCallbackCount == 0);
|
||||
await _waitUntilFrame(() => SchedulerBinding.instance!.transientCallbackCount == 0);
|
||||
|
||||
await _waitUntilFrame(() => finder.evaluate().isEmpty);
|
||||
|
||||
if (_frameSync)
|
||||
await _waitUntilFrame(() => SchedulerBinding.instance.transientCallbackCount == 0);
|
||||
await _waitUntilFrame(() => SchedulerBinding.instance!.transientCallbackCount == 0);
|
||||
|
||||
return finder;
|
||||
}
|
||||
@ -372,7 +372,7 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
||||
if (element is! RenderObjectElement) {
|
||||
return false;
|
||||
}
|
||||
final String semanticsLabel = element.renderObject?.debugSemantics?.label;
|
||||
final String? semanticsLabel = element.renderObject.debugSemantics?.label;
|
||||
if (semanticsLabel == null) {
|
||||
return false;
|
||||
}
|
||||
@ -449,7 +449,7 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
||||
return _createDescendantFinder(finder as Descendant);
|
||||
default:
|
||||
if (_finderExtensions.containsKey(finder.finderType)) {
|
||||
return _finderExtensions[finder.finderType].createFinder(finder);
|
||||
return _finderExtensions[finder.finderType]!.createFinder(finder);
|
||||
} else {
|
||||
throw 'Unsupported finder type: ${finder.finderType}';
|
||||
}
|
||||
@ -477,7 +477,7 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
||||
return const WaitForAbsentResult();
|
||||
}
|
||||
|
||||
Future<Result> _waitForCondition(Command command) async {
|
||||
Future<Result?> _waitForCondition(Command command) async {
|
||||
assert(command != null);
|
||||
final WaitForCondition waitForConditionCommand = command as WaitForCondition;
|
||||
final WaitCondition condition = deserializeCondition(waitForConditionCommand.condition);
|
||||
@ -489,9 +489,9 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
||||
'This method has been deprecated in favor of _waitForCondition. '
|
||||
'This feature was deprecated after v1.9.3.'
|
||||
)
|
||||
Future<Result> _waitUntilNoTransientCallbacks(Command command) async {
|
||||
if (SchedulerBinding.instance.transientCallbackCount != 0)
|
||||
await _waitUntilFrame(() => SchedulerBinding.instance.transientCallbackCount == 0);
|
||||
Future<Result?> _waitUntilNoTransientCallbacks(Command command) async {
|
||||
if (SchedulerBinding.instance!.transientCallbackCount != 0)
|
||||
await _waitUntilFrame(() => SchedulerBinding.instance!.transientCallbackCount == 0);
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -518,10 +518,10 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
||||
'This method has been deprecated in favor of _waitForCondition. '
|
||||
'This feature was deprecated after v1.9.3.'
|
||||
)
|
||||
Future<Result> _waitUntilNoPendingFrame(Command command) async {
|
||||
Future<Result?> _waitUntilNoPendingFrame(Command command) async {
|
||||
await _waitUntilFrame(() {
|
||||
return SchedulerBinding.instance.transientCallbackCount == 0
|
||||
&& !SchedulerBinding.instance.hasScheduledFrame;
|
||||
return SchedulerBinding.instance!.transientCallbackCount == 0
|
||||
&& !SchedulerBinding.instance!.hasScheduledFrame;
|
||||
});
|
||||
return null;
|
||||
}
|
||||
@ -534,11 +534,11 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
||||
throw StateError('Found more than one element with the same ID: $elements');
|
||||
}
|
||||
final Element element = elements.single;
|
||||
RenderObject renderObject = element.renderObject;
|
||||
SemanticsNode node;
|
||||
RenderObject? renderObject = element.renderObject;
|
||||
SemanticsNode? node;
|
||||
while (renderObject != null && node == null) {
|
||||
node = renderObject.debugSemantics;
|
||||
renderObject = renderObject.parent as RenderObject;
|
||||
renderObject = renderObject.parent as RenderObject?;
|
||||
}
|
||||
if (node == null)
|
||||
throw StateError('No semantics data found');
|
||||
@ -549,7 +549,7 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
||||
final GetOffset getOffsetCommand = command as GetOffset;
|
||||
final Finder finder = await _waitForElement(_createFinder(getOffsetCommand.finder));
|
||||
final Element element = finder.evaluate().single;
|
||||
final RenderBox box = element.renderObject as RenderBox;
|
||||
final RenderBox box = (element.renderObject as RenderBox?)!;
|
||||
Offset localPoint;
|
||||
switch (getOffsetCommand.offsetType) {
|
||||
case OffsetType.topLeft:
|
||||
@ -579,7 +579,7 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
||||
DiagnosticsNode diagnosticsNode;
|
||||
switch (diagnosticsCommand.diagnosticsType) {
|
||||
case DiagnosticsType.renderObject:
|
||||
diagnosticsNode = element.renderObject.toDiagnosticsNode();
|
||||
diagnosticsNode = element.renderObject!.toDiagnosticsNode();
|
||||
break;
|
||||
case DiagnosticsType.widget:
|
||||
diagnosticsNode = element.toDiagnosticsNode();
|
||||
@ -615,7 +615,11 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
||||
Future<ScrollResult> _scrollIntoView(Command command) async {
|
||||
final ScrollIntoView scrollIntoViewCommand = command as ScrollIntoView;
|
||||
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();
|
||||
}
|
||||
|
||||
@ -624,7 +628,7 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
||||
final Finder target = await _waitForElement(_createFinder(getTextCommand.finder));
|
||||
|
||||
final Widget widget = target.evaluate().single.widget;
|
||||
String text;
|
||||
String? text;
|
||||
|
||||
if (widget.runtimeType == Text) {
|
||||
text = (widget as Text).data;
|
||||
@ -634,9 +638,9 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
||||
text = (richText.text as TextSpan).text;
|
||||
}
|
||||
} else if (widget.runtimeType == TextField) {
|
||||
text = (widget as TextField).controller.text;
|
||||
text = (widget as TextField).controller?.text;
|
||||
} else if (widget.runtimeType == TextFormField) {
|
||||
text = (widget as TextFormField).controller.text;
|
||||
text = (widget as TextFormField).controller?.text;
|
||||
} else if (widget.runtimeType == EditableText) {
|
||||
text = (widget as EditableText).controller.text;
|
||||
}
|
||||
@ -670,7 +674,9 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
||||
|
||||
Future<RequestDataResult> _requestData(Command command) async {
|
||||
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 {
|
||||
@ -679,24 +685,24 @@ class FlutterDriverExtension with DeserializeFinderFactory {
|
||||
return const SetFrameSyncResult();
|
||||
}
|
||||
|
||||
SemanticsHandle _semantics;
|
||||
bool get _semanticsIsEnabled => RendererBinding.instance.pipelineOwner.semanticsOwner != null;
|
||||
SemanticsHandle? _semantics;
|
||||
bool get _semanticsIsEnabled => RendererBinding.instance!.pipelineOwner.semanticsOwner != null;
|
||||
|
||||
Future<SetSemanticsResult> _setSemantics(Command command) async {
|
||||
final SetSemantics setSemanticsCommand = command as SetSemantics;
|
||||
final bool semanticsWasEnabled = _semanticsIsEnabled;
|
||||
if (setSemanticsCommand.enabled && _semantics == null) {
|
||||
_semantics = RendererBinding.instance.pipelineOwner.ensureSemantics();
|
||||
_semantics = RendererBinding.instance!.pipelineOwner.ensureSemantics();
|
||||
if (!semanticsWasEnabled) {
|
||||
// wait for the first frame where semantics is enabled.
|
||||
final Completer<void> completer = Completer<void>();
|
||||
SchedulerBinding.instance.addPostFrameCallback((Duration d) {
|
||||
SchedulerBinding.instance!.addPostFrameCallback((Duration d) {
|
||||
completer.complete();
|
||||
});
|
||||
await completer.future;
|
||||
}
|
||||
} else if (!setSemanticsCommand.enabled && _semantics != null) {
|
||||
_semantics.dispose();
|
||||
_semantics!.dispose();
|
||||
_semantics = null;
|
||||
}
|
||||
return SetSemanticsResult(semanticsWasEnabled != _semanticsIsEnabled);
|
||||
|
@ -49,12 +49,12 @@ class _InternalNoTransientCallbacksCondition implements WaitCondition {
|
||||
}
|
||||
|
||||
@override
|
||||
bool get condition => SchedulerBinding.instance.transientCallbackCount == 0;
|
||||
bool get condition => SchedulerBinding.instance!.transientCallbackCount == 0;
|
||||
|
||||
@override
|
||||
Future<void> wait() async {
|
||||
while (!condition) {
|
||||
await SchedulerBinding.instance.endOfFrame;
|
||||
await SchedulerBinding.instance!.endOfFrame;
|
||||
}
|
||||
assert(condition);
|
||||
}
|
||||
@ -77,12 +77,12 @@ class _InternalNoPendingFrameCondition implements WaitCondition {
|
||||
}
|
||||
|
||||
@override
|
||||
bool get condition => !SchedulerBinding.instance.hasScheduledFrame;
|
||||
bool get condition => !SchedulerBinding.instance!.hasScheduledFrame;
|
||||
|
||||
@override
|
||||
Future<void> wait() async {
|
||||
while (!condition) {
|
||||
await SchedulerBinding.instance.endOfFrame;
|
||||
await SchedulerBinding.instance!.endOfFrame;
|
||||
}
|
||||
assert(condition);
|
||||
}
|
||||
@ -105,11 +105,11 @@ class _InternalFirstFrameRasterizedCondition implements WaitCondition {
|
||||
}
|
||||
|
||||
@override
|
||||
bool get condition => WidgetsBinding.instance.firstFrameRasterized;
|
||||
bool get condition => WidgetsBinding.instance!.firstFrameRasterized;
|
||||
|
||||
@override
|
||||
Future<void> wait() async {
|
||||
await WidgetsBinding.instance.waitUntilFirstFrameRasterized;
|
||||
await WidgetsBinding.instance!.waitUntilFirstFrameRasterized;
|
||||
assert(condition);
|
||||
}
|
||||
}
|
||||
@ -132,13 +132,13 @@ class _InternalNoPendingPlatformMessagesCondition implements WaitCondition {
|
||||
|
||||
@override
|
||||
bool get condition {
|
||||
final TestDefaultBinaryMessenger binaryMessenger = ServicesBinding.instance.defaultBinaryMessenger as TestDefaultBinaryMessenger;
|
||||
final TestDefaultBinaryMessenger binaryMessenger = ServicesBinding.instance!.defaultBinaryMessenger as TestDefaultBinaryMessenger;
|
||||
return binaryMessenger.pendingMessageCount == 0;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> wait() async {
|
||||
final TestDefaultBinaryMessenger binaryMessenger = ServicesBinding.instance.defaultBinaryMessenger as TestDefaultBinaryMessenger;
|
||||
final TestDefaultBinaryMessenger binaryMessenger = ServicesBinding.instance!.defaultBinaryMessenger as TestDefaultBinaryMessenger;
|
||||
while (!condition) {
|
||||
await binaryMessenger.platformMessagesFinished;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ author: Flutter Authors <flutter-dev@googlegroups.com>
|
||||
|
||||
environment:
|
||||
# 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:
|
||||
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
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.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
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'package:flutter_driver/flutter_driver.dart';
|
||||
import 'package:flutter_driver/src/common/find.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
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'package:flutter_driver/src/extension/_extension_io.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
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'dart:convert' show json;
|
||||
|
||||
import 'package:file/file.dart';
|
||||
|
@ -2,6 +2,8 @@
|
||||
// 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';
|
||||
|
@ -2,6 +2,8 @@
|
||||
// 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';
|
||||
|
@ -9,4 +9,4 @@ analyzer:
|
||||
always_require_non_null_named_parameters: false # not needed with nnbd
|
||||
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 # 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