Skip to content

Commit c49f37a

Browse files
Add support for drag and drop (#10)
* add pumpAndTrySettle instead of pumpAndTry * Added support for drag and drop and also use pumpAndTrySettle
1 parent 2767ded commit c49f37a

File tree

8 files changed

+113
-7
lines changed

8 files changed

+113
-7
lines changed

demo-app/lib/screens/loader_screen.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class _LoaderScreenState extends State<LoaderScreen> {
4444
),
4545
child: const Text(
4646
"Login",
47+
key: ValueKey("loader_login_button"),
4748
style: TextStyle(color: Colors.white),
4849
),
4950
),
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import 'package:appium_flutter_server/src/handler/request/request_handler.dart';
2+
import 'package:appium_flutter_server/src/models/api/appium_response.dart';
3+
import 'package:appium_flutter_server/src/utils/element_helper.dart';
4+
import 'package:flutter_test/flutter_test.dart';
5+
import 'package:shelf_plus/shelf_plus.dart';
6+
import 'package:appium_flutter_server/src/models/api/drag_drop.dart';
7+
8+
class DragAndDrop extends RequestHandler {
9+
DragAndDrop(super.route);
10+
11+
@override
12+
Future<AppiumResponse> handle(Request request) async {
13+
var sessionId = getSessionId(request);
14+
DragAndDropModel model =
15+
DragAndDropModel.fromJson(await request.body.asJson);
16+
await ElementHelper.dragAndDrop(model);
17+
return AppiumResponse(sessionId, null);
18+
}
19+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import 'package:appium_flutter_server/src/models/api/find_element.dart';
2+
import 'package:json_annotation/json_annotation.dart';
3+
import 'package:appium_flutter_server/src/models/api/element.dart';
4+
5+
part 'generated/drag_drop.g.dart';
6+
7+
@JsonSerializable()
8+
class DragAndDropModel {
9+
ElementModel source;
10+
ElementModel target;
11+
int? dragDuration;
12+
13+
DragAndDropModel(
14+
{required this.source,
15+
required this.target,
16+
this.dragDuration});
17+
18+
factory DragAndDropModel.fromJson(Map<String, dynamic> json) =>
19+
_$DragAndDropModelFromJson(json);
20+
21+
Map<String, dynamic> toJson() => _$DragAndDropModelToJson(this);
22+
}

server/lib/src/models/api/generated/drag_drop.g.dart

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

server/lib/src/runner.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ void initializeTest({Widget? app, Function? callback}) async {
3030
var appInfo = await PackageInfo.fromPlatform();
3131
// Need a better way to fetch this for automated release, this needs to be updated along with version bump
3232
// Can stay for now as it is not a breaking change
33-
var serverVersion = '0.0.11';
33+
var serverVersion = '0.0.12';
3434
FlutterDriver.instance
3535
.initialize(tester: tester, binding: binding, appInfo: appInfo, serverVersion: serverVersion);
3636
//await tester.pumpWidget(app);

server/lib/src/server.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import 'package:shelf_plus/shelf_plus.dart' as shelf_plus;
2525

2626
import 'package:appium_flutter_server/src/handler/clear.dart';
2727

28+
import 'handler/gesture/drag_drop.dart';
2829
import 'handler/long_press.dart';
2930

3031
enum HttpMethod { GET, POST, DELETE, PUT, PATCH }
@@ -77,6 +78,8 @@ class FlutterServer {
7778
"/session/<sessionId>/appium/gestures/double_click"));
7879
_registerPost(ScrollTillVisibleHandler(
7980
"/session/<sessionId>/appium/gestures/scroll_till_visible"));
81+
_registerPost(DragAndDrop(
82+
"/session/<sessionId>/appium/gestures/drag_drop"));
8083

8184
/* Wait handlers */
8285
_registerPost(

server/lib/src/utils/element_helper.dart

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import 'package:appium_flutter_server/src/exceptions/flutter_automation_error.da
77
import 'package:appium_flutter_server/src/internal/element_lookup_strategy.dart';
88
import 'package:appium_flutter_server/src/internal/flutter_element.dart';
99
import 'package:appium_flutter_server/src/logger.dart';
10+
import 'package:appium_flutter_server/src/models/api/drag_drop.dart';
1011
import 'package:appium_flutter_server/src/models/api/gesture.dart';
1112
import 'package:appium_flutter_server/src/models/api/find_element.dart';
1213
import 'package:appium_flutter_server/src/models/session.dart';
@@ -71,7 +72,7 @@ class ElementHelper {
7172
static Future<void> click(FlutterElement element) async {
7273
WidgetTester tester = _getTester();
7374
await tester.tap(element.by);
74-
await tester.pumpAndSettle();
75+
await pumpAndTrySettle();
7576
}
7677

7778
static Future<void> setText(FlutterElement element, String text) async {
@@ -117,7 +118,7 @@ class ElementHelper {
117118
await tester.pump(kDoubleTapMinTime);
118119
await tester.tapAt(Offset(bounds.left + doubleClickModel.offset!.x,
119120
bounds.top + doubleClickModel.offset!.y));
120-
await tester.pumpAndSettle();
121+
await pumpAndTrySettle();
121122
}
122123
}
123124
});
@@ -128,7 +129,7 @@ class ElementHelper {
128129
await tester.tap(element.by);
129130
await tester.pump(kDoubleTapMinTime);
130131
await tester.tap(element.by);
131-
await tester.pumpAndSettle();
132+
await pumpAndTrySettle();
132133
}
133134

134135
static Future<void> longPress(GestureModel longPressModel) async {
@@ -162,7 +163,7 @@ class ElementHelper {
162163
log("Click by offset $bounds");
163164
await tester.longPressAt(
164165
Offset(longPressModel.offset!.x, longPressModel.offset!.y));
165-
await tester.pumpAndSettle();
166+
await pumpAndTrySettle();
166167
}
167168
}
168169
});
@@ -444,12 +445,30 @@ class ElementHelper {
444445
: 'Timed out waiting for condition');
445446
}
446447
if (Platform.isAndroid) {
447-
await tester.pumpAndSettle();
448+
await pumpAndTrySettle(timeout: const Duration(milliseconds: 200));
448449
}
449450
await Future.delayed(const Duration(milliseconds: 100));
450451
} while (!(await predicate()));
451452
}
452453

454+
static Future<void> dragAndDrop(DragAndDropModel model) async {
455+
return TestAsyncUtils.guard(() async {
456+
WidgetTester tester = _getTester();
457+
final String sourceElementId = model.source.id;
458+
final String targetElementId = model.target.id;
459+
Session session = FlutterDriver.instance.getSessionOrThrow()!;
460+
FlutterElement sourceEl = await session.elementsCache.get(sourceElementId);
461+
FlutterElement targetEl = await session.elementsCache.get(targetElementId);
462+
final Offset sourceElementLocation = tester.getCenter(sourceEl.by);
463+
final Offset targetElementLocation = tester.getCenter(targetEl.by);
464+
final TestGesture gesture = await tester.startGesture(sourceElementLocation, pointer: 7);
465+
await gesture.moveTo(targetElementLocation);
466+
await tester.pump();
467+
await gesture.up();
468+
await tester.pump();
469+
});
470+
}
471+
453472
static Future<Finder> scrollUntilVisible({
454473
required FindElementModel finder,
455474
FindElementModel? scrollView,
@@ -540,4 +559,25 @@ class ElementHelper {
540559
return const Uuid().v4();
541560
}
542561
}
562+
static Future<void> pumpAndTrySettle({
563+
Duration duration = const Duration(milliseconds: 100),
564+
EnginePhase phase = EnginePhase.sendSemanticsUpdate,
565+
Duration timeout = const Duration(milliseconds: 200),
566+
}) async {
567+
try {
568+
WidgetTester tester = _getTester();
569+
await tester.pumpAndSettle(
570+
duration,
571+
phase,
572+
timeout,
573+
);
574+
} on FlutterError catch (err) {
575+
if (err.message == 'pumpAndSettle timed out') {
576+
//This method ignores pumpAndSettle timeouts on purpose
577+
} else {
578+
rethrow;
579+
}
580+
}
581+
}
582+
543583
}

server/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: appium_flutter_server
22
description: "Appium Flutter server using Integration Test package for testing Flutter apps with Appium"
3-
version: 0.0.11
3+
version: 0.0.12
44
homepage: "https://github.com/AppiumTestDistribution/appium-flutter-server"
55

66
environment:

0 commit comments

Comments
 (0)