Add a `exists` function to `NativeAutomator`
When writing tests that open a browser, on Firebase Test Lab there is a cookie banner but when I run them on my local device, the banner is already closed. This introduces two paths of execution in a native view.
What I'd like to do is to check if there is a text in the browser, and if there is, click it. Something like:
final cookieSelector = Selector(text: 'Accept cookies');
if ($.native.exists(cookieSelector)) {
$.native.tap(cookieSelector);
}
Or, maybe allow native.tap to not find given selector:
final cookieSelector = Selector(text: 'Accept cookies');
$.native.tap(cookieSelector, throwIfNotFound: false);
Currently my work around is an extension on PatrolIntegrationTester:
Future<void> nativeTryTapText(String text) async {
try {
await native.tap(Selector(text: text));
} on PatrolActionException catch (e) {
if (e.message.contains('NOT_FOUND')) {
return;
}
rethrow;
}
}
Not sure if it's technically possible to check if there is a match on a Selector before trying to tap it but if so, such functions could be helpful. :)
Update
I just found out there is getNativeViews function in NativeAutomator.
So my extension is now:
extension NativeAutomatorEx on NativeAutomator {
Future<bool> exists(Selector selector, {String? appId}) async =>
(await getNativeViews(selector, appId: appId)).isNotEmpty;
Future<void> tapIfExists(String text) async {
final selector = Selector(text: text);
if (await exists(selector)) {
await tap(selector);
}
}
}
This means the package allows me to do what I wanted :) Maybe the exists function should be a part of the package as well? Up to you, if you don't want to add it, the ticket can be closed :)
Hi, generally your approach using getNativeViews is correct and that's the recommended way of handling with such cases. Let's leave the ticket open, I like your idea because it makes the API easier to use.
related to: https://github.com/leancodepl/patrol/issues/2280