leancodepl / patrol

Flutter-first UI testing framework. Ready for action!
https://patrol.leancode.co
Apache License 2.0
898 stars 135 forks source link

Support for Flutter Web Apps in Patrol #733

Open appbieger opened 1 year ago

appbieger commented 1 year ago

I have an iOS and Android project that uses Patrol for testing. We are now working on a web port of the project and would like to use our existing Patrol tests for the web version as well. However, as far as I understand, it is currently not possible to use any subset of our tests on the web version because Patrol does not support Flutter Web Apps.

Is there a possibility that Patrol will support Flutter Web Apps in the near future? This would be a huge help for our project and would greatly improve our testing workflow. Thank you for considering this request.

bartekpacia commented 1 year ago

Hi @appbieger, it's great to hear that Patrol works for you :) And thanks for raising this feature request.

Patrol basically consists of 2 components:

The former depends only on pure Flutter, so I see no reason why it shouldn't work on Flutter Web. (That said, I haven't got much experience with UI tests on Flutter Web, so I might be missing something)

The latter depends on the underlying platform frameworks (UIAutomator2 for Android and XCUITest for iOS), and I don't know how it relates to the web. Is it already possible to tap a browser-default popup with Flutter finders on web?

FWIW, my project lead (@mateuszwojtczak) and I evaluated how Patrol could support Flutter Web some time ago and it seemed to be possible, but we're currently focusing exclusively on mobile. That said, if you'd like to share some useful info or contribute, we're more than happy :)

jaxnz commented 1 year ago

Having web support would be amazing. We already use the default flutter integration testing, but patrol is much better.

I am trying to do a bundled_test for the web, but it says no devices attached. Is it possible to add chrome as a device?

bartekpacia commented 1 year ago

Is it possible to add chrome as a device

Unfortunately, it's not. Currently, we have iOS and Android hardcoded, and other platforms are simply ignored. It can be changed quite easily, but web is not our priority right now.

Out of curiosity, what specific Patrol features do you want to use on the Web?

jaxnz commented 1 year ago

The main attraction towards patrol for the web is the removing the huge amount of boilerplate code and support for the bundling of tests with one run of the app.

bartekpacia commented 1 year ago

The main attraction towards patrol for the web is the removing the huge amount of boilerplate code

If you only want to use this feature, then you're good to go :) Patrol basically consists of 2 main features: custom finders and native automation. The first depends only on Flutter itself, so you can it use everywhere where Flutter runs.

If you're only using custom finders, then you can run your tests with flutter test, as usual :).

bundling of tests with one run of the app.

This is also possible to do on the web.

jaxnz commented 1 year ago

bundling of tests with one run of the app.

This is also possible to do on the web.

The documented example requires the use of patrol drive - no?

bartekpacia commented 1 year ago

Yeah, because we're currently focused on mobile only, so it makes sense to include such instructions. Sorry about the confusion.

If you want to run it on the web, you can just do run it with flutter test and it should work.

jaxnz commented 1 year ago

Just for reference for other web users, we can still use bundled testing as per the Patrol Documentation and Custom Finders:

flutter drive --driver=test_driver/integration_test.dart --target=integration_test/bundled_test.dart

Jonas-Sander commented 1 year ago

Running my tests (don't use any $.native functionality) doesn't work for me, this might be because we assume that clearPackageData is true in our tests. I'll need to investigate further.

@jaxnz did you need to call IntegrationTestWidgetsFlutterBinding.ensureInitialized(); when running the tests for web?

flutter drive --driver=test_driver/integration_test.dart --target=integration_test/bundled_test.dart

Is --target=integration_test/bundled_test.dart the file auto-generated by the CLI? For me this file is called test_bundle.dart. Or is it just a regular test file?

I assumed, one needs to set nativeAutomation: false when running the tests for the web, correct? Otherwise they are skipped for me.

Jonas-Sander commented 1 year ago

Generally I think this is a very important feature as otherwise one would have to write the same tests using patrol and then via the stock integration_test package to do the same thing.

I was a bit surprised to be honest that nothing regarding web is written in the patrol README or documentation, as I would assume most users would switch from already written stock integration_test tests to patrol and need to keep running tests for web as well. This is at least my use case.

iam-shanmichael commented 1 year ago

Just for reference for other web users, we can still use bundled testing as per the Patrol Documentation and Custom Finders:

flutter drive --driver=test_driver/integration_test.dart --target=integration_test/bundled_test.dart

@Jonas-Sander hi , does it mean you can run integration test on --headless mode not in --no-headless mode ?

on my end it's open a browser to your integration but not simulating , no error in console after all and all testing is passed

here is my command to run my integration test:

flutter drive \ --driver=test_driver/integration_test.dart \ --target=integration_test/features/authentication/page/login_authentication_test.dart \ -d web-server --no-headless

Screen Shot 2023-10-31 at 5 50 45 PM
Jonas-Sander commented 11 months ago

@Jonas-Sander hi , does it mean you can run integration test on --headless mode not in --no-headless mode ?

on my end it's open a browser to your integration but not simulating , no error in console after all and all testing is passed

I usually run them in headless mode. I tried --no-headless as well but then the chrome window opens with our loading indicator but nothing else happens afterwards.

nilsreichardt commented 7 months ago

Just for reference for other web users, we can still use bundled testing as per the Patrol Documentation and Custom Finders:

flutter drive --driver=test_driver/integration_test.dart --target=integration_test/bundled_test.dart

@jaxnz Cou you explain this more? In my this doesn't work because test_bundle.dart includes NativeAutomator which uses dart:io:

flutter drive \
   --driver=test_driver/integration_test.dart \
   --target=integration_test/test_bundle.dart \
   -d chrome

Error:

Launching integration_test/test_bundle.dart on Chrome in debug mode...
Waiting for connection from debug service on Chrome...             51.2s
This app is linked to the debug service: ws://127.0.0.1:63914/YB-Gr9KxslU=/ws
Debug service listening on ws://127.0.0.1:63914/YB-Gr9KxslU=/ws
Error: Unsupported operation: Platform._operatingSystem
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 297:3       throw_
dart-sdk/lib/_internal/js_dev_runtime/patch/io_patch.dart 244:5                   _operatingSystem
dart-sdk/lib/io/platform_impl.dart 56:40                                          get operatingSystem
dart-sdk/lib/io/platform.dart 83:44                                               get operatingSystem
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 1293:8  get
dart-sdk/lib/io/platform.dart 156:50                                              get isAndroid
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 1293:8  get
packages/patrol/src/native/native_automator.dart 181:52                           new
test_bundle.dart 48:27                                                            main
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 84:54                runBody
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 127:5                _async
test_bundle.dart 15:18                                                            main
web_entrypoint.dart 24:31                                                         <fn>
lib/ui_web/ui_web/initialization.dart 41:9                                        <fn>
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 45:50                <fn>
dart-sdk/lib/async/zone.dart 1661:54                                              runUnary
dart-sdk/lib/async/future_impl.dart 162:18                                        handleValue
dart-sdk/lib/async/future_impl.dart 838:44                                        handleValueCallback
dart-sdk/lib/async/future_impl.dart 867:13                                        _propagateToListeners
dart-sdk/lib/async/future_impl.dart 643:5                                         [_completeWithValue]
dart-sdk/lib/async/future_impl.dart 713:7                                         callback
dart-sdk/lib/async/schedule_microtask.dart 40:11                                  _microtaskLoop
dart-sdk/lib/async/schedule_microtask.dart 49:5                                   _startMicrotaskLoop
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 181:7                <fn>