Skip to content

Commit d9a3abb

Browse files
Implement find elements
1 parent 75ef703 commit d9a3abb

File tree

6 files changed

+101
-22
lines changed

6 files changed

+101
-22
lines changed

.prettierrc

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
2-
"semi": true,
3-
"printWidth": 80
4-
}
2+
"semi": true,
3+
"printWidth": 80
4+
}

lib/src/handler/find_elements.dart

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import 'package:appium_flutter_server/src/driver.dart';
2+
import 'package:appium_flutter_server/src/exceptions/element_not_found_exception.dart';
3+
import 'package:appium_flutter_server/src/handler/request/request_handler.dart';
4+
import 'package:appium_flutter_server/src/internal/element_lookup_strategy.dart';
5+
import 'package:appium_flutter_server/src/internal/flutter_element.dart';
6+
import 'package:appium_flutter_server/src/logger.dart';
7+
import 'package:appium_flutter_server/src/models/api/appium_response.dart';
8+
import 'package:appium_flutter_server/src/models/api/element.dart';
9+
import 'package:appium_flutter_server/src/models/api/find_element.dart';
10+
import 'package:appium_flutter_server/src/models/session.dart';
11+
import 'package:appium_flutter_server/src/utils/element_helper.dart';
12+
import 'package:flutter_test/flutter_test.dart';
13+
import 'package:shelf_plus/shelf_plus.dart';
14+
15+
class FindElementstHandler extends RequestHandler {
16+
FindElementstHandler(super.route);
17+
18+
@override
19+
Future<AppiumResponse> handle(Request request) async {
20+
FindElementModel model =
21+
FindElementModel.fromJson(await request.body.asJson);
22+
23+
final String method = model.strategy;
24+
final String selector = model.selector;
25+
final String? contextId = model.context == "" ? null : model.context;
26+
27+
if (contextId == null) {
28+
log('"method: $method, selector: $selector');
29+
} else {
30+
log('"method: $method, selector: $selector, contextId: $contextId');
31+
}
32+
33+
Session? session = FlutterDriver.instance.getSessionOrThrow();
34+
final Finder by = ElementLookupStrategy.values
35+
.firstWhere((val) => val.name == method)
36+
.toFinder(selector);
37+
List<Finder> matchedByList = [];
38+
try {
39+
matchedByList =
40+
await ElementHelper.findElements(by, contextId: contextId);
41+
} on ElementNotFoundException catch (e) {
42+
log("Got an exception while looking for multiple matches using method: $method, selector: $selector");
43+
log(e);
44+
return AppiumResponse(session!.sessionId, matchedByList);
45+
}
46+
47+
if (matchedByList.isEmpty) {
48+
log("Found zero matches");
49+
return AppiumResponse(session!.sessionId, matchedByList);
50+
}
51+
52+
List<ElementModel> result = [];
53+
for (Finder by in matchedByList) {
54+
FlutterElement flutterElement = await session!.elementsCache.add(by);
55+
result.add(ElementModel.fromElement(flutterElement.id));
56+
}
57+
58+
return AppiumResponse(getSessionId(request), result);
59+
}
60+
}

lib/src/handler/request/request_handler.dart

-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ import 'package:appium_flutter_server/src/models/api/appium_response.dart';
55
import 'package:appium_flutter_server/src/models/session.dart';
66
import 'package:shelf_plus/shelf_plus.dart';
77

8-
enum HttpMethod { GET, POST, DELETE, PUT, PATCH }
9-
108
abstract class RequestHandler {
119
final String route;
1210

lib/src/internal/widget_predicates.dart

-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ WidgetPredicate filterByIconCode(int iconCode) {
2121
return false;
2222
}
2323
Icon iconWidget = widget as Icon;
24-
log('$WidgetName.Icon.name => ${iconWidget.icon!.codePoint} => ${iconCode}');
2524
return iconWidget.icon!.codePoint == iconCode;
2625
};
2726
}

lib/src/server.dart

+23-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'package:appium_flutter_server/src/handler/delete_session.dart';
22
import 'package:appium_flutter_server/src/handler/find_element.dart';
3+
import 'package:appium_flutter_server/src/handler/find_elements.dart';
34
import 'package:appium_flutter_server/src/handler/new_session.dart';
45
import 'package:appium_flutter_server/src/handler/request/request_handler.dart';
56
import 'package:appium_flutter_server/src/handler/sample/screenshot.dart';
@@ -9,6 +10,8 @@ import 'package:appium_flutter_server/src/logger.dart';
910
import 'package:appium_flutter_server/src/utils.dart';
1011
import 'package:shelf_plus/shelf_plus.dart' as shelf_plus;
1112

13+
enum HttpMethod { GET, POST, DELETE, PUT, PATCH }
14+
1215
class FlutterServer {
1316
final bool _isStarted = false;
1417
late shelf_plus.RouterPlus _app;
@@ -28,17 +31,29 @@ class FlutterServer {
2831

2932
void _registerRoutes() {
3033
//GET ROUTES
31-
_addRoute(HttpMethod.GET, StatusHandler("/status"));
32-
_addRoute(HttpMethod.GET, ScreenshotHandler("/screenshot"));
33-
_addRoute(HttpMethod.GET, TapHandler("/tap"));
34+
_registerGet(StatusHandler("/status"));
35+
_registerGet(ScreenshotHandler("/screenshot"));
36+
_registerGet(TapHandler("/tap"));
3437

3538
//POST ROUTES
36-
_addRoute(HttpMethod.POST, NewSessionHandler("/session"));
37-
_addRoute(
38-
HttpMethod.POST, FindElementHandler("/session/<sessionId>/element"));
39+
_registerPost(NewSessionHandler("/session"));
40+
_registerPost(FindElementHandler("/session/<sessionId>/element"));
41+
_registerPost(FindElementstHandler("/session/<sessionId>/elements"));
42+
43+
//DELETE ROUTES
44+
_registerDelete(DeleteSessionHandler("/session/<sessionId>"));
45+
}
46+
47+
void _registerGet(RequestHandler handler) {
48+
_addRoute(HttpMethod.GET, handler);
49+
}
50+
51+
void _registerPost(RequestHandler handler) {
52+
_addRoute(HttpMethod.POST, handler);
53+
}
3954

40-
//DELETE
41-
_addRoute(HttpMethod.DELETE, DeleteSessionHandler("/session/<sessionId>"));
55+
void _registerDelete(RequestHandler handler) {
56+
_addRoute(HttpMethod.DELETE, handler);
4257
}
4358

4459
void startServer({int? port}) async {

lib/src/utils/element_helper.dart

+15-8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import 'dart:math';
2+
13
import 'package:appium_flutter_server/src/driver.dart';
24
import 'package:appium_flutter_server/src/exceptions/element_not_found_exception.dart';
35
import 'package:appium_flutter_server/src/internal/flutter_element.dart';
@@ -7,6 +9,12 @@ import 'package:flutter_test/flutter_test.dart';
79

810
class ElementHelper {
911
static Future<Finder> findElement(Finder by, {String? contextId}) async {
12+
List<Finder> elementList = await findElements(by, contextId: contextId);
13+
return elementList.first;
14+
}
15+
16+
static Future<List<Finder>> findElements(Finder by,
17+
{String? contextId}) async {
1018
Session? session = FlutterDriver.instance.getSessionOrThrow();
1119
WidgetTester tester = FlutterDriver.instance.tester;
1220
Finder finder = by;
@@ -20,16 +28,15 @@ class ElementHelper {
2028
finder = find.descendant(of: parent.by, matching: by);
2129
}
2230

23-
final Iterable<Element> element = finder.evaluate();
24-
if (element.isEmpty) {
31+
final Iterable<Element> elements = finder.evaluate();
32+
if (elements.isEmpty) {
2533
throw ElementNotFoundException("Unable to locate element");
2634
}
2735

28-
return finder.at(0);
36+
List<Finder> elementList = [];
37+
for (int i = 0; i < elements.length; i++) {
38+
elementList.add(finder.at(i));
39+
}
40+
return elementList;
2941
}
30-
31-
// Future<Element> _findElementFromContext(
32-
// Finder by, Session session, WidgetTester tester, String contextId) async {
33-
// return null;
34-
// }
3542
}

0 commit comments

Comments
 (0)