feat(integration_test): add a WidgetTester app driver adapter

This commit is contained in:
Jon Samwell 2021-01-07 14:14:16 +11:00
parent 68f3a6e6db
commit f1fb2d4a63
9 changed files with 244 additions and 14 deletions

View File

@ -1,5 +1,6 @@
{
"cSpell.words": [
"Serializable"
"Serializable",
"scrollable"
]
}

View File

@ -0,0 +1 @@
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"integration_test","path":"C:\\\\Google\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\integration_test-1.0.1\\\\","dependencies":[]}],"android":[{"name":"integration_test","path":"C:\\\\Google\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\integration_test-1.0.1\\\\","dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"integration_test","dependencies":[]}],"date_created":"2021-01-07 13:34:08.388534","version":"1.22.5"}

File diff suppressed because one or more lines are too long

View File

@ -2,7 +2,6 @@ import 'dart:async';
enum FindType {
key,
pageBack,
text,
tooltip,
type,
@ -79,6 +78,8 @@ abstract class AppDriverAdapter<TRawAdapter, TFinderType, TWidgetBaseType> {
Duration timeout = const Duration(seconds: 30),
});
Future<void> pageBack();
Future<void> scroll(
TFinderType finder, {
double dx = 0,
@ -88,7 +89,7 @@ abstract class AppDriverAdapter<TRawAdapter, TFinderType, TWidgetBaseType> {
});
Future<void> scrollUntilVisible(
TFinderType parent,
TFinderType scrollable,
TFinderType item, {
double dx = 0,
double dy = 0,

View File

@ -152,8 +152,6 @@ class FlutterDriverAppDriverAdapter
switch (type) {
case FindType.key:
return find.byValueKey(data);
case FindType.pageBack:
return find.pageBack();
case FindType.text:
return find.text(data);
case FindType.tooltip:
@ -197,14 +195,14 @@ class FlutterDriverAppDriverAdapter
@override
Future<void> scrollUntilVisible(
SerializableFinder parent,
SerializableFinder scrollable,
SerializableFinder item, {
double dx = 0,
double dy = 0,
Duration timeout = const Duration(seconds: 30),
}) async {
await rawDriver.scrollUntilVisible(
parent,
scrollable,
item,
timeout: timeout,
dxScroll: dx,
@ -222,4 +220,9 @@ class FlutterDriverAppDriverAdapter
timeout: timeout,
);
}
@override
Future<void> pageBack() async {
await tap(find.pageBack());
}
}

View File

@ -0,0 +1,219 @@
import 'dart:async';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import 'app_driver_adapter.dart';
class WidgetTesterAppDriverAdapter
extends AppDriverAdapter<WidgetTester, Finder, Widget> {
WidgetTesterAppDriverAdapter(WidgetTester rawAdapter) : super(rawAdapter);
@override
Future<int> waitForAppToSettle({
Duration duration = const Duration(milliseconds: 100),
Duration timeout = const Duration(seconds: 30),
}) async {
try {
await rawDriver.pumpAndSettle(
duration,
EnginePhase.sendSemanticsUpdate,
timeout,
);
} catch (_) {
return null;
}
return null;
}
@override
Future<T> widget<T extends Widget>(Finder finder) {
return Future.value(rawDriver.widget<T>(finder));
}
@override
Future<List<int>> screenshot() {
var renderObject = rawDriver.binding.renderViewElement.renderObject;
while (!renderObject.isRepaintBoundary) {
renderObject = renderObject.parent as RenderObject;
assert(renderObject != null);
}
assert(!renderObject.debugNeedsPaint);
final layer = renderObject.debugLayer as OffsetLayer;
return layer
.toImage(renderObject.paintBounds)
.then((value) => value.toByteData())
.then((value) => value.buffer.asInt64List());
}
@override
Future<bool> isPresent(
Finder finder, {
Duration timeout = const Duration(seconds: 1),
}) async {
try {
final element = await widget(finder);
return element != null;
} on StateError {
return false;
}
}
@override
Future<bool> isAbsent(
Finder finder, {
Duration timeout = const Duration(seconds: 1),
}) async {
return await isPresent(finder).then((value) => !value);
}
@override
Future<String> getText(
Finder finder, {
Duration timeout = const Duration(seconds: 30),
}) async {
await waitForAppToSettle(timeout: timeout);
final instance = await widget(finder);
if (instance is Text) {
return instance.data;
} else if (instance is TextSpan) {
return (instance as TextSpan).text;
}
throw Exception(
'Unable to get text from unknown type `${instance.runtimeType}`');
}
@override
Future<void> enterText(
Finder finder,
String text, {
Duration timeout = const Duration(seconds: 30),
}) async {
await tap(
finder,
timeout: timeout,
);
await rawDriver.enterText(
finder,
text,
);
}
@override
Future<void> tap(
Finder finder, {
Duration timeout = const Duration(seconds: 30),
}) async {
await rawDriver.tap(finder);
await waitForAppToSettle(timeout: timeout);
}
@override
Future<void> longPress(
Finder finder, {
Duration pressDuration = const Duration(milliseconds: 500),
Duration timeout = const Duration(seconds: 30),
}) async {
await scroll(
finder,
dx: 0,
dy: 0,
duration: pressDuration,
timeout: timeout,
);
await waitForAppToSettle(timeout: timeout);
}
@override
Future<void> scroll(
Finder finder, {
double dx = 0,
double dy = 0,
Duration duration = const Duration(seconds: 200),
Duration timeout = const Duration(seconds: 30),
}) async {
await rawDriver.scrollUntilVisible(
finder,
dx,
duration: duration,
);
await waitForAppToSettle(timeout: timeout);
}
@override
Finder findBy(String data, FindType type) {
switch (type) {
case FindType.key:
return find.byKey(ValueKey(data));
case FindType.text:
return find.text(data);
case FindType.tooltip:
return find.byTooltip(data);
case FindType.type:
// return find.byType(data);
}
throw Exception('unknown finder');
}
@override
Finder findByAncestor(
Finder of,
Finder matching, {
bool matchRoot = false,
bool firstMatchOnly = false,
}) {
return find.ancestor(
of: of,
matching: matching,
matchRoot: matchRoot,
);
}
@override
Finder findByDescendant(
Finder of,
Finder matching, {
bool matchRoot = false,
bool firstMatchOnly = false,
}) {
return find.descendant(
of: of,
matching: matching,
matchRoot: matchRoot,
);
}
@override
Future<void> scrollUntilVisible(
Finder scrollable,
Finder item, {
double dx = 0,
double dy = 0,
Duration timeout = const Duration(seconds: 30),
}) async {
await rawDriver.scrollUntilVisible(
item,
dx,
scrollable: scrollable,
);
}
@override
Future<void> scrollIntoView(
Finder finder, {
Duration timeout = const Duration(seconds: 30),
}) async {
await rawDriver.ensureVisible(finder);
}
@override
Future<void> pageBack() async {
await rawDriver.pageBack();
}
}

View File

@ -1,4 +1,3 @@
import 'package:flutter_gherkin/src/flutter/adapters/app_driver_adapter.dart';
import 'package:flutter_gherkin/src/flutter/flutter_world.dart';
import 'package:gherkin/gherkin.dart';
@ -13,9 +12,7 @@ StepDefinitionGeneric WhenTapBackButtonWidget() {
return when<FlutterWorld>(
RegExp(r'I tap the back (?:button|element|widget|icon|text)$'),
(context) async {
await context.world.appDriver.tap(
context.world.appDriver.findBy(null, FindType.pageBack),
);
await context.world.appDriver.pageBack();
},
);
}

View File

@ -168,6 +168,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.4"
integration_test:
dependency: "direct main"
description:
name: integration_test
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
io:
dependency: transitive
description:
@ -462,4 +469,4 @@ packages:
version: "2.2.1"
sdks:
dart: ">=2.10.0-110 <2.11.0"
flutter: ">=1.13.0"
flutter: ">=1.13.0 <2.0.0"

View File

@ -1,6 +1,6 @@
name: flutter_gherkin
description: A Gherkin / Cucumber parser and test runner for Dart and Flutter
version: 1.1.9
version: 1.2.0
homepage: https://github.com/jonsamwell/flutter_gherkin
environment:
@ -16,6 +16,7 @@ dependencies:
sdk: flutter
glob: ^1.1.7
meta: ">=1.1.6 <2.0.0"
integration_test: ^1.0.1
gherkin: ^1.1.9
# gherkin:
# path: ../dart_gherkin